WordPressに追加したプラグインの翻訳は、プラグインの言語フォルダなどに入れたファイルを読み込ませるか、サイト本体の翻訳ディレクトリにファイルを入れるかのいずれかで適用されるようになるのはご存じかと思います。
一般的にプラグインの翻訳を適用させる場合は以下のようなコードをプラグイン内に書きますね。
function pwcn_load_textdomain() {
load_plugin_textdomain(
'テキストドメイン名',
false,
dirname( plugin_basename( __FILE__ ) ) . '/languages'
);
}
add_action( 'plugins_loaded', 'pwcn_load_textdomain' );
これが、WordPress6.7以降では「plugins_loaded」にフックさせていると以下のように表示されたり、エラーログに記録されたりするようになるようです(以下はWordPress 6.7Beta1時点で実際に表示されたものです)。
Notice: Function _load_textdomain_just_in_time was called incorrectly. Translation loading for the [texdomain name] domain was triggered too early. This is usually an indicator for some code in the plugin or theme running too early. Please see Debugging in WordPress for more information. (This message was added in version 6.7.0.) in /…/wp-includes/functions.php on line 6099
日本語に訳すと
注意: 関数 _load_textdomain_just_in_time が誤って呼び出されました。[texdomain名] ドメインの翻訳の読み込みが早すぎました。これは通常、プラグインまたはテーマのコードが早すぎたことを示しています。詳細については、WordPress のデバッグを参照してください。(このメッセージはバージョン 6.7.0 で追加されました。) /…/wp-includes/functions.php の 6099 行目
と書かれており、読み込みが早すぎるということのようです。
まあNoticeなので警告でもエラーでもないので、様子見でもいいとは思いますが、エラーを調べるためにデバッグモードを有効にしていると基本的に毎度表示されてしまう(ログ出力している場合にはログがどんどん増える)ので、気になる人は対処しておきたいものだと思います。
これを回避するには「plugins_loaded」よりも遅い(テーマの設定情報が読み込まれた後に発火する)「after_setup_theme()」や「init()」を使えばOKなのですが、そうすると、ブロックエディターなどに追加したブロックスタイルなどの翻訳が効かなくなることがあります(あくまでも私がテストした限りではこの事象が発生しました)。
この問題も回避して確実に翻訳を適用する最も正確な方法としては、サイトの翻訳ディレクトリ(「wp-content」→「languages」→「plugins」)へファイルを適用することではあるものの、公式のプラグインとして登録しているものでない場合には、もちろん自動で翻訳は落ちてこないですし、そこここで紹介されている「upgrader_process_complete()」関数は、プラグイン一覧から更新を走らせた時だけ有効のようで、アップロード更新時には動作しないので、その方法も使えません。
そこでいろいろと試行錯誤して、WordPress公式のプラグインディレクトリ上で配布していない(いわゆる野良プラグイン)でもこの不具合を解消する方法を見つけましたので参考までに公開しておきます。
お断りしておきますが、公開時点でWordPress6.7はベータ1バージョンであり、公式リリース時にどうなっているのかも分かりませんし、あくまでも私の場合の解決法ですのでそのあたりを承知の上で読んでいただければと思います。
【方法】本体の翻訳ファイルと比較して上書きを行う
この不都合というか不具合を解消するには、プラグインディレクトリ内に設置した翻訳ファイル用のディレクトリ(通常は「languages」ディレクトリ)にある翻訳ファイルをサイト本体の翻訳ディレクトリ(「wp-content」→「languages」→「plugins」)へコピーする機能を設けることです。
さらに、プラグインディレクトリ側の翻訳を正として、本体の翻訳ディレクトリと比較し、古い場合には上書き更新するという機能も必要になります。
以下が対応用コードです。
* プラグインの読み込み時に翻訳ファイルを確認して更新 */
/* アップロード更新の場合に「upgrader_process_complete」フックは効かないためにこの措置にした */
/* プラグインディレクトリ側のファイルと、本体の翻訳ディレクトリ側のファイルの日付を比較して更新 */
function pwcn_update_languages_files() {
$lang_dir = WP_LANG_DIR . '/plugins/';
$locales = [
'ja' => ['ここに正式な翻訳ファイル名'],
//ロケールが追加されたらここにファイルの配列を追加
];
$source_dir = plugin_dir_path(__FILE__) . 'languages/';
foreach ($locales as $locale => $files) {
foreach ($files as $file_name) {
$source_file = $source_dir . $file_name;
$target_file = $lang_dir . $file_name;
if (file_exists($source_file)) {
// ターゲットファイルが存在する場合、日付を比較
if (file_exists($target_file)) {
if (filemtime($source_file) > filemtime($target_file)) {
// プラグイン内のファイルが新しい場合はコピー
copy($source_file, $target_file);
}
} else {
// ターゲットファイルが存在しない場合はコピー
copy($source_file, $target_file);
}
} else {
error_log("Translation file not found: " . $source_file);
}
}
}
}
add_action('plugins_loaded', 'pwcn_update_languages_files');
上記のコードはプラグインディレクトリ内に「languages」ディレクトリがあり、そこに翻訳ファイルがある場合ですので、異なる場合には10行目付近の「languages」の文字列を適切なディレクトリへ書き換える必要があります。
また、「ここに正式な翻訳ファイル名」の部分には翻訳ファイル名と拡張子を記述する必要があります。
.mo .l10n.php .jsonなど複数のファイルがある場合には、「,」で区切って追加します。
例:’〇〇-ja.mo’, ‘〇〇-ja.po’, ‘〇〇-ja.l10n.php’,’〇〇-ja.json’
これで、基本的にこのコードを設置しておけば、管理画面で画面遷移したり、フロントエンドへのアクセスがある度(要はそのプラグインがロードされる度)に
- サイトの翻訳ディレクトリにファイルがなければ追加
- サイトの翻訳ディレクトリにあるファイルよりもプラグインの翻訳フォルダにあるファイルが新しければ書き換え
という動作をしますから、常に最新の状態を保つことができます。
そもそも元の翻訳ファイルの読み込みで「plugin_loaded」にフックさせて似たようなことをしていたわけですから、特に動作に負荷がかかるということもないでしょう。
また、このコードを書いておくことで、サイトの翻訳ディレクトリにある翻訳は特別に読み込まなくても確実にサイトへ読み込まれますから、以下のような翻訳ファイル読み込みのコードも不要になります。
逆にinitで読み込ませた場合には一部の翻訳が効かないというトラブルが発生する可能性があるので書かない方が無難かも知れません。
function pwcn_load_textdomain() {
load_plugin_textdomain(
'テキストドメイン名',
false,
dirname( plugin_basename( __FILE__ ) ) . '/languages'
);
}
add_action( 'plugins_loaded', 'pwcn_load_textdomain' );
または
add_action( 'init', 'pwcn_load_textdomain', 1 );
さらに、プラグインを使わなくなった時にサイトの翻訳ディレクトリへ余分なファイルを残さないよう、以下のようなコードを使ってプラグインの停止(削除)時にそれらのファイルを削除するようにしておくといいでしょう。
/* プラグイン無効化時に翻訳ファイルを削除 */
function pwcn_delete_languages_files() {
$lang_dir = WP_LANG_DIR . '/plugins/';
$locales = [
'ja' => ['ここに正式な翻訳ファイル名'],
// 他のロケールを追加
];
foreach ($locales as $locale => $files) {
foreach ($files as $file_name) {
$file_path = $lang_dir . $file_name;
if (file_exists($file_path)) {
unlink($file_path);
}
}
}
}
//register_uninstall_hook(__FILE__, 'pwcn_delete_languages_files');//削除時
register_deactivation_hook(__FILE__, 'pwcn_delete_languages_files');//停止時
ここまでWordPress6.7で発生するNoticeとなる事項を予見して書いてきましたが、そうでなくても基本的にこのコードで書いておけば問題は起きませんし、きちんと翻訳も当たるので、個人的にはこれが翻訳を確実に適用させるベストな方法だと思いますので、今後何かのプラグインを作る(配布する)際にはこの手法で行く予定です。
コメントを残す