サイトアイコン Capital P

Before Gutenberg – JavaScript多言語化の新しい形

Gutenbergはそのソースの多くがJavaScriptから構成されている。そこで問題となるのが多言語対応(Internationalizationを略してi18nなどと書く)なのだが、これまでは次のようにやや迂遠な方法を使っていた。

// PHP
wp_enqueue_scripts( 'my-script' );
wp_localize_script( 'my-script', 'MyScript', [
    'title'             => __( 'My Script', 'my-domain' ),
    'description' => __( 'This is my script.', 'my-domain' ),
] );

//JS
alert( MyScript.title );

要するに、これまではPHPで翻訳した文字列を定義し、それをwp_localize_script関数でパスしていたわけだ。

この方法のダルいところは、JavaScriptを書いている最中に、わざわざPHPファイルを開かなければならないところである。いったりきたりしているうちに、「あれ、なにしようとしてたんだっけ?」と記憶喪失になってしまい、twitterやfacebookで時間を潰し始め、気づいたら2時間ぐらい経っていたという事態がよく発生する。

こうした問題点(?)を解消すべく、GutenbergおよびWordPress 5.0ではJavaScriptに直接翻訳関数を書くことができる。いまのところ、GutenbergとWordPress 5.0ではちょっとやり方が異なるのだが、基本的にはPHPで利用していたのと同じドメイン指定でできる形に変わった。

// JS読み込み時に、wp-i18nを依存関係に追加する。
wp_enqueue_script( 'my-script', $url, [ 'wp-i18n', 'jquery' ], $version, true );
// Gutenbergのちょっと古いやり方
if ( function_exists( 'gutenberg_get_jed_locale_data' ) ) {
	$json = json_encode( gutenberg_get_jed_locale_data( 'my-domain' ) );
	wp_add_inline_script(
		'my-script',
		sprintf( 'wp.i18n.setLocaleData(  %s, "my-domain" );', $json ),
		'before'
	);
}
// WordPress 5.0
if ( function_exists( 'wp_set_script_translations' ) ) {
	wp_set_script_translations( 'my-script', 'my-domain' );
}

このように書いておくと、JavaScript内で見慣れた___xといった翻訳関数が使えるようになる。

// 関数を読み込み
const { __ } = wp.i18n;

alert( __( 'My Script', 'my-domain' ) );

これでPHPとJSを行ったり来たりすることによる記憶喪失も防げるだろう。

追記・翻訳用JSONを作成する必要がある?

※2020年1月9日さらに追記 WordPress 5.3ぐらいからGlotPress(WordPressの翻訳プラットフォーム)がJSの解析にも対応したようで、少なくとも公式リポジトリで配布する場合は翻訳用のJSONを書き出す必要は無くなった。よって、以下のパートはすでに無効になった情報も幾分含んでいる。(タレコミはCapital P会員の大橋直記さん)

さて、この記事を公開後、WordPress 5.0がリリースされたが、SnowMonkeyの北島氏よりツッコミが入った。

筆者も自身でリリースしたWP-YomiganaをWordPress 5.0に対応したところ、翻訳が聞いていないことが判明。公式ブログのリリース確認したところ、以下のようなことがわかった。

Translation and Language packs support for plugins and themes that are hosted on the repo is expected in the upcoming weeks. The patches are ready and waiting for commit.

要するに、上記で紹介した方法ではまだ翻訳されないようだ。GlotPress経由でも翻訳が変更された印象はない。よって、Advanced Usageとして紹介される情報によると翻訳用のJSONを作成し、それを指定することで翻訳が適用される。

また、上記で紹介した方法は「WordPress.orgで公開されるプラグイン・テーマ」に限る。したがって、自分で販売しているテーマやプラグインは別の方法を取る必要がある。

ステップ1. 翻訳用JSONを作成する

さて、これまでになかった処理として、poファイルから翻訳用JSONを生成しなければならない。これにはnpmパッケージを利用する。

npm install po2json

このコマンドをnpmスクリプトなどに追加して、翻訳対象のpoファイルを指定すると、JSONが生成される。JSONの命名規則は{$domain}-{$locale}-{$handle}.jsonとなる。

po2json languages/wp-yomigana-ja.po languages/wp-yomigana-ja-definition-list.json -f jed

ステップ2. 翻訳を読み込む

続いて、wp_enqueue_scriptで読み込む時に、wp_set_script_translationsを実行する。ハンドルごとに実行することを忘れないように。引数の順番はハンドル名、ドメイン、翻訳ファイルのディレクトリ。

wp_register_script( 'wp-yomigana-dl', $this->assets . '/js/dist/definition-list.js', [ 'wp-i18n' ], '1.0.0', true );
wp_set_script_translations( 'wp-yomigana-dl', 'wp-yomigana', plugin_dir_path(  __DIR__  ) ) . 'languages' );

これで無事翻訳が適用された。

雑感

さて、実際にやってみて、問題がありそうだなと思ったのは下記の点だ。

おまけ 翻訳対象のスクレイピング

さて、テーマやプラグインを作っている方は、翻訳対象となる文字列をpotファイルなどに書き出していることだろう。おそらく、WordPressの公式翻訳プラットフォームであるGlotPressを使えば悩むことはないだろうが、自作テーマや販売用テーマなどを使っている方は、potファイルを作成する方法がこれまでとは変わることになる。いままではPHPファイルだけをスクレイピングすればよかったのだが、今度はJSが追加されるからだ。

方法1 WP-CLI

WordCamp Tokyo 2018にもきていたPascal Birchlerが勧めるように、WP-CLIのパッケージコマンドを追加することで、翻訳対象をいい感じに抽出できる。

package install wp-cli/i18n-command
wp i18n make-pot

npmスクリプトと組み合わせれば、自動で書き出すこともできるだろう。

方法2 PoEdit

PoEditは古くからあるGUIの翻訳カタログエディタである。こちらではデフォルトでJSが無視されるので、まずは「カタログ > 設定 > ソースのパス」にある無視リストからJS *.js を外そう。

続いて、これはgettext業界ではわりと知られたハックらしいのだが、翻訳対象の抽出としてJavaScriptは入っていないので、表記が似ているPythonを採用するようだ。「設定 > 抽出ツール」を選んでPythonを編集し、次のような設定にする。

Pytonの設定部分を書き換えるとJSも有効になる。

これで今まで通りのワークフローが使えるはずだ。

以上、プラグインやテーマ作者の頭を悩ませていたJavaScriptの翻訳めんどくさい問題が片付いたので、WordPress 5.0からは気軽にJSに文字列を書くことができるだろう。

モバイルバージョンを終了