WordPress 英語サイト作成時に翻訳ファイルが読み込めない

  • -

    シェア
  • ---

    LINEで送る
  • -

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

    pocket
  • -

    rss
他言語サイト
us us
wordpress image

日本語サイトをベースに英語サイトを作成したとき、英語サイトのテーマディレクトリに翻訳ファイル(en_US.mo)を設置しました。

けれど、デバッグしてみると翻訳ファイルが読み込まれない。

その原因の調査結果、解決策です。(WordPress 4.8.1 - 4.9.6)

間違った設定を行っていないか確認

まず、設定が間違っていると調査する意味はないので確認します。

確認内容は以下の通りです。

  • __() or _e()は使っているか?
  • __() or _e()の第2引数にドメインテキストが指定されているか?
  • functions.phpの定義に間違いはないか?
  • 翻訳ファイルの設置場所に間違いはないか?

__() or _e()の使い方に間違いはありませんでした。

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

xeory_base_customは、xeory_baseのテーマを自分用にカスタマイズした子テーマです。

次にfunctions.phpの定義に間違いはないか確認しました。

/**
* 子テーマの翻訳ファイル定義
*/
function language_child() {
    load_child_theme_textdomain( 'xeory_base_custom', get_stylesheet_directory() . '/languages' );
}
add_action( 'after_setup_theme', 'language_child' );

定義に問題はありません。そもそも、前に別のテーマで使っていた定義をコピペしてきたものなので間違いはないはずです。
そのときは英語のテーマを日本語に翻訳したのですが、正常に動作していました。

英語用翻訳ファイルen_US.moファイルは、xeory_base_custom/languages/に設置しています。

設定に間違いありません。

こうなったらWordPressのソースを追跡する

この設定でなぜ翻訳ファイルが読み込まれないのか分かりません。悩んでてもラチがあかないのでソースコードを追跡します。

まずは、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 );
}

ここでは、.moファイルの設置パスが未指定の場合、テーマのホームディレクトリを設定しているだけです。

次へ行きましょう。

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' );
}

$localeでは、日本語サイトはjp、英語サイトではen_USになります。

問題は、31行目の load_textdomain()です。ここでは、テーマディレクトリではなく、Document/wp-content/languages/themes/のxeory_base_custom-en_US.moファイルを読み込もうとします。

デバッグをしたところ必ずtrueが返ってきます。指定したパスの.moファイル読み込みは、最終行で行われるので、これでは.moファイルを読み込むはずもありません。

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;
}

問題は、33行目のapply_filters( 'override_load_textdomain', false, $domain, $mofile )の部分です。これが必ずtrueを返します。

これでは、設置した翻訳ファイルの内容が反映されません。

うしろの処理

  • .moファイルを読み込む
  • オブジェクト(new MO)にマージした結果を格納
  • グローバル変数$l10n[]に挿入

が行なわれません。

この行の意味は、.moファイルの読み込みの上書きを無効にするかどうかをフィルタリングするものです。

WordPressのリファレンス(over_load_textdomain)にそう書いてあります。

3番目の引数で上書きしない(false)を指定しているので、デフォルトはfalseを返すはずです。ということはどこかで'override_load_textdomain'のhookに対してtrueを返すように指定しているはずです。

そこで、WordPressのDocumentRoot配下全域で検索をかけてみました。

すると、BackWPupプラグインで "add_filter( 'override_load_textdomain', '__return_true' );" を記述している箇所が2つもありました。

テーマのfunctions.phpを修正する

修正方法は簡単です。テーマのfunctions.phpファイルに次の記述を追記します。

add_filter( 'override_load_textdomain', '__return_false' );

add_filterの第2引数で'__return_false'を指定すると、フィルタの関数で必ずfalseを返すようになります。

まとめ

原因はBackWPupプラグインにありました。プラグインの記述によってテーマの翻訳ファイルにまで影響していました。

あとは自分のWordPressに対する知識不足でしょう。この投稿を最初に書いたときはWordPressを使い始めて間もないころで不慣れでした。

filterの使い方をあまり知らずに書いたため、必要のない暫定処理を書いていました。

きちんとした修正方法が見つかったので、これでWordPressのアップデートがあっても大丈夫です。

(暫定処理はWordpressのソースを直接編集していた。)

2018/07/18
暫定措置の内容を残そうとも思いましたが、最終的にたどり着いた原因・対策とかけ離れているので、ぜんぶ削除しました。

 

最近Webカテゴリでよく読まれている記事です。
post-cta-image
blog image

ドメイン取得の意味が分からない人へ。王道の方法を紹介します。

ドメインの登録業者を選ぶのに悩む必要はないです。サイトを簡単に早く公開するには全くいらないことで、むしろ邪魔です。『お名前.com』というサービスは必ず耳にします。そのお名前.comのメリットとデメリットと一緒に、ドメインの意味が分からない人が一番失敗しないドメインの取得方法を紹介します。

tadtadya.com

_

SNSでも記事を配信しています。

コメント

  1. ただ屋ぁ より:

    WordPress 4.8.2 にバージョンアップしたので同じような暫定措置を入れました。

  2. ただ屋ぁ より:

    WordPress 4.8.3にバージョンアップしたので同じような暫定措置を入れました。

  3. ただ屋ぁ より:

    WordPress 4.9にバージョンアップしたので同じような暫定措置を入れました。

  4. ただ屋ぁ より:

    暫定措置から正規の修正方法に変更しました。
    WordPress 4.9.2に対応しています。

コメントを残す

*

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

この記事を気に入ったらぜひシェアも!!