WordPress: Translation file is not loaded

Other language site
ja ja
Google Translate
  • -

    シェア
  • ---

    LINEで送る
  • -

    はてなブックマーク
    ブックマーク
  • -

    pocket
  • -

    rss
WordPress logo

When creating an English site based on a Japanese site, we simply set up a translation file (en_US.mo) on the English site.

Next, I defined functions.php to call load_child_theme_textdomain () with the after_setup_theme action.

However, when I try to debug it I can not read the translation file.

The result of investigating the cause, the solution. (WordPress 4.8.1 - 4.9.2)

I checked whether I made a wrong setting

First of all, since it is meaningless to investigate that the setting is incorrect, I will confirm.

The details of the confirmation are as follows.

  • __ () or _e () is used?
  • Is domain text specified as the second argument of __ () or _e ()?
  • Is there a mistake in the definition in functions.php?
  • Is there a mistake in setting up the translation file?

There was no mistake in how to use __ () or _e ().

<?php the_content(__('続きを読む', 'xeory_base_custom')); ?>

"続きを読む" means "read more".

"xeory_base_custom" is a child theme that I customized the theme of "xeory_base".

Next, I confirmed that there is no mistake in the definition of functions.php.

/**
* Translation file definition of child theme
*/
function language_child() {
    load_child_theme_textdomain( 'xeory_base_custom', get_stylesheet_directory() . '/languages' );
}
add_action( 'after_setup_theme', 'language_child' );

There is no problem in definition.

In the first place, there is no mistake because it has copied the definition used before when using another theme.

At that time I translated the English theme into Japanese, but it worked normally.

English translation file "en_US.mo" file is installed in "xeory_base_custom/languages/".

There seems to be no mistake in setting.

I chose to track WordPress source

I do not know why translation files are not loaded in this setting.

Since it makes no sense to stop working, it tracks the source code.

First of all, it is load_child_theme_textdomain().

load_child_theme_textdomain()

/●●●/DocumentRoot/wp-includes/l10n.php Line:806

/**
* Load the child themes translated strings.
*
* If the current locale exists as a .mo file in the child themes
* root directory, it will be included in the translated strings by the $domain.
*
* The .mo files must be named based on the locale exactly.
*
* @since 2.9.0
*
* @param string $domain Text domain. Unique identifier for retrieving translated strings.
* @param string $path Optional. Path to the directory containing the .mo file.
* Default false.
* @return bool True when the theme textdomain is successfully loaded, false otherwise.
*/
function load_child_theme_textdomain( $domain, $path = false ) {
    if ( ! $path )
        $path = get_stylesheet_directory();
    return load_theme_textdomain( $domain, $path );
}

Here, if the installation path of the .mo file is unspecified, it is only setting the theme home directory.

Let's go next.

load_theme_domain()

/●●●/DocumentRoot/wp-includes/l10n.php Line:764

/**
* Load the theme's translated strings.
*
* If the current locale exists as a .mo file in the theme's root directory, it
* will be included in the translated strings by the $domain.
*
* The .mo files must be named based on the locale exactly.
*
* @since 1.5.0
* @since 4.6.0 The function now tries to load the .mo file from the languages directory first.
*
* @param string $domain Text domain. Unique identifier for retrieving translated strings.
* @param string $path Optional. Path to the directory containing the .mo file.
* Default false.
* @return bool True when textdomain is successfully loaded, false otherwise.
*/
function load_theme_textdomain( $domain, $path = false ) {
    /**
    * Filters a theme's locale.
    *
    * @since 3.0.0
    *
    * @param string $locale The theme's current locale.
    * @param string $domain Text domain. Unique identifier for retrieving translated strings.
    */
    $locale = apply_filters( 'theme_locale', is_admin() ? get_user_locale() : get_locale(), $domain );

    $mofile = $domain . '-' . $locale . '.mo';

    // Try to load from the languages directory first.
    if ( load_textdomain( $domain, WP_LANG_DIR . '/themes/' . $mofile ) ) {
        return true;
    }

    if ( ! $path ) {
        $path = get_template_directory();
    }

    return load_textdomain( $domain, $path . '/' . $locale . '.mo' );
}

In $locale, the Japanese site is "jp", in the English site it is "en_US".

The problem is load_textdomain() on line 31.

Here, srouce tries to read the "xeory_base_custom-en_US.mo" file of "DocumentRoot/wp-content/languages/themes/" instead of the theme directory.

I always return true when I debug.

Reading .mo files of the specified path will be done on the last line, so there is no way to load .mo files with this.

Let's look at load_textdomain().

load_textdomain()

/●●●/DocumentRoot/wp-includes/l10n.php Line:523

/**
* Load a .mo file into the text domain $domain.
*
* If the text domain already exists, the translations will be merged. If both
* sets have the same string, the translation from the original value will be taken.
*
* On success, the .mo file will be placed in the $l10n global by $domain
* and will be a MO object.
*
* @since 1.5.0
*
* @global array $l10n An array of all currently loaded text domains.
* @global array $l10n_unloaded An array of all text domains that have been unloaded again.
*
* @param string $domain Text domain. Unique identifier for retrieving translated strings.
* @param string $mofile Path to the .mo file.
* @return bool True on success, false on failure.
*/
function load_textdomain( $domain, $mofile ) {
    global $l10n, $l10n_unloaded;

    $l10n_unloaded = (array) $l10n_unloaded;

    /**
    * Filters whether to override the .mo file loading.
    *
    * @since 2.9.0
    *
    * @param bool $override Whether to override the .mo file loading. Default false.
    * @param string $domain Text domain. Unique identifier for retrieving translated strings.
    * @param string $mofile Path to the MO file.
    */
    $plugin_override = apply_filters( 'override_load_textdomain', false, $domain, $mofile );

    if ( true == $plugin_override ) {
        unset( $l10n_unloaded[ $domain ] );

        return true;
    }

    /**
    * Fires before the MO translation file is loaded.
    *
    * @since 2.9.0
    *
    * @param string $domain Text domain. Unique identifier for retrieving translated strings.
    * @param string $mofile Path to the .mo file.
    */
    do_action( 'load_textdomain', $domain, $mofile );

    /**
    * Filters MO file path for loading translations for a specific text domain.
    *
    * @since 2.9.0
    *
    * @param string $mofile Path to the MO file.
    * @param string $domain Text domain. Unique identifier for retrieving translated strings.
    */
    $mofile = apply_filters( 'load_textdomain_mofile', $mofile, $domain );

    if ( !is_readable( $mofile ) ) return false;

    $mo = new MO();
    if ( !$mo->import_from_file( $mofile ) ) return false;

    if ( isset( $l10n[$domain] ) )
         $mo->merge_with( $l10n[$domain] );

    unset( $l10n_unloaded[ $domain ] );

    $l10n[$domain] = &$mo;

    return true;
}

The problem is the part of apply_filters('override_load_textdomain', false, $ domain, $ mofile) on line 33.

This always returns true.

Then, the process of reading the .mo file and storing the result of merging it into the object (new MO) will not be done.

Also, it is not inserted into the global variable "$l10n[]".

In other words, the content of the installed translation file is not reflected.

What this line means is to filter whether to override the overwriting of loading of .mo files.

It says so in WordPress' s reference (over_load_textdomain).

< 2018/01/19 Correction>

The third argument specifies not to overwrite (false), so the default should return false.
That means you should have specified something to return true for 'override_load_textdomain' hook.

So we tried searching across WordPress' s DocumentRoot.

Then, there were two places where "add_filter ('override_load_textdomain', '__return_true');" is written in the "BackWPup" plugin.

Since it specifies not to overwrite (false) with the third argument, it is probably returning overwrite prohibition (true) as a result.

In that case, should we apply apply_filters('override_load_textdomain', true, $ domain, $ mofile) beforehand in functions.php?

I thought, I ran it.

apply_filters( 'override_load_textdomain', true, $domain, $mofile )

The changes of functions.php are as follows.

/**
* Translation file definition of child theme
*/
function language_child() {
    $modir = get_stylesheet_directory() . '/languages';
    $mofile = $modir . '/en_US.mo';
    $domain = 'xeory_base_custom';
    apply_filters( 'override_load_textdomain', true, $domain, $mofile );
    load_child_theme_textdomain( $domain, $modir );
}
add_action( 'after_setup_theme', 'language_child' );

When this is done, both Japanese and English sites should be Englishized.

Originally should include conditions other than the Japanese site, but it is not included for the first investigation.

Then a strange result appeared.

The Japanese site was rendered English, but the English site did not read the translation file and it remained in Japanese.

The value returned by override_load_textdomain was "[][]" for the Japanese site and "true" for the English site.

"[][]" Will be empty 2D array data.

It is not "false".

It was a totally unexpected result.

For further investigation, you must output the keywords of the filters registered with "add_filter" and examine the contents.

It was interrupted because it can easily be imagined that it takes time.

I thought of a good strategy but I got stuck.

I decided to add interim processing for the time being

What I was looking for was that the Japanese site was intact and the English site was to read the English translation file.

As a result it has been reversed, so it can not be realized with this.

Looking at the result of "override_load_textdomain", it seems that translation files matching $ locale can not be read.

I decided to add interim processing to WordPress php file.

In advance, functions.php will be returned before using override_load_textdomain.

/●●●/DocumentRoot/wp-includes/l10n.php Line:557 load_textdomain()

if ( $domain !== "xeory_base_custom" ) {
    if ( true == $plugin_override ) {
        unset( $l10n_unloaded[ $domain ] );

        return true;
    }
}

Processing is simple.

I skip the overwrite filter results only when I am using theme.

Fix theme functions.php

The correction method is simple. Add the following description in the functions.php file of the theme.

add_filter( 'override_load_textdomain', '__return_false' );

If '__return_false' is specified as the second argument of add_filter, the filter function always returns false.

Conclusion

After all, it did not reach the cause identification.

Even though it was working properly in the previous theme (Catch Box).

Perhaps it is a matter of a theme?

It was stated that the Xeory Base theme does not correspond to foreign languages.

It caught in the meaning that no translation file was prepared.

What can be thought of is that we are operating at multi site, the main site is Japanese site and the subsite is English site.

This may be influenced.

Is it a bug in the subsite?

There is no confirmation.

 

Well, this fix is bad cool.

It will disappear if there is WordPress update.

I just could not find any other way.

For now, I will look at the situation for a while with provisional processing.

The cause was in the "BackWPup" plug-in. The description of the plugin also affected the translation file of the theme.

Another thing is lack of knowledge of my WordPress. When I wrote this post for the first time, I was not used to it when I started using WordPress soon.

I wrote without knowing how to use filter, so I wrote a temporary process that I do not need.

I found a neat fix, so it's okay with WordPress updates.

SNS also distributes articles.

コメント

  1. tadaya says:

    I updated to WordPress 4.8.2, so I did the same provisional processing.

  2. tadaya says:

    I updated to WordPress 4.8.3, so I did the same provisional processing.

  3. tadaya says:

    I updated to WordPress 4.9, so I did the same provisional processing.

  4. tadaya says:

    I changed from temporary correction to regular correction method.
    It corresponds to WordPress 4.9.2.

Leave a Reply

*

If you like this article, share it!