「WordPress の言語別機能とそのあり方」
スピーカーは倉石さんです。
よろしくお願いします!
倉石政典です。
みなさん、 WordPress 4.0 で
言語まわりの大きな変化があったのを
覚えてますでしょうか。
WPLANG 定数が非推奨となり、
Language chooser で言語の master value を
設定するように
変更が行われました。
こちらの画像は、日本語のインストールで
外部ネットワークに繋がっていないものと
仮定してください
「インストール済み」に、英語と日本語があり
言語が日本語に設定されています。
この状態で
日本語の翻訳ファイルを削除します。
すると、インストール済みの文字列が
英語表記の Installed に変わり
そこから、日本語が消えて
英語だけになってしまいました。
下には、「Available」と書いてありますが
翻訳ファイルを手に入れられない環境では
言語を日本語に設定することはできません。
これは一体、どういうことでしょうか。
それは、翻訳ファイルの存在がある場合に限り
言語設定ができる
という仕様変更が
バージョン4.0で行われたからです。
なぜ、このような制限が
加えられたのでしょうか。
それは「翻訳ファイル集約主義」の
考えによるものです。
これは、WordPress のコア開発で
現在主流となっている
言語別機能に関する実装方式です。
ぼくが勝手に名づけて
そう呼んでいるだけです。
そういうコンセプトがある、ということを
理解していただければと思います。
どういうものか
言葉で定義するならば、
「言語ファイルに、各言語の特性を
機能レベルまで集約させて
一元的に管理するという考え」
このコンセプトを推し進めてきたのは
といった感じになると思います。
リードデベロッパー、アンドリューネイシンです。
彼はほんのすこし前まで、IAT の
国際化の責任者をしていました。
「翻訳ファイル集約主義」
という基本アイディアを
彼が考えたのかはわかりませんが
どのように実装するかは彼が中心となって
考えていたと思います。
これから少しネガティブな話をしますが
僕は、基本的には彼のことが大好きで
尊敬できるすばらしい人物だと思っていますので
誤解しないよう、よろしくお願いします。
僕は、彼が国際化の責任者の立場から離れた時
本当に寂しく感じました。
彼は多くの労力を費やして
英語圏以外のユーザーのために
WordPress をよくしてきてくれました。
ネイシンありがとう。
この場を借りて、心から礼をいいたいと思います。
でも、安心してください。
次の i18n 責任者も素晴らしい人です。
ニューネイシンこと、
オーシャンナイン、
ドミニクシニグさんです。
国際化関連の新しい技術責任者ですので
覚えておいてください。
何か困ったことがあったときは
きっと力になってくれると思います。
翻訳ファイル集約主義の実装について
具体的に説明します。
例えば、このような PHP のコードがあるとします。
_x というのは、
コンテキストの 2番目のパラメータにくる翻訳関数です
画面の内容を説明しますと、
第1パラメーターの 'words' は、
翻訳対象文字列であり、ID
第2パラメーターの
'word count: words, characters or all?' は、
ID のコンテキストを示す追加文字列です。
この部分が違えば、翻訳対象の ID が同じでも
衝突すること無く
別のものとして訳すことができる
という仕組みです。
先ほどの x から抽出された翻訳ファイル内の
エントリーがこちらになります。
msgctxt が、コンテキスト
msgid が、翻訳対象文字列
msgstr は、翻訳語の文字列です。
ワーズ?などで、のあとにある単語などに訳されるはずですが、
ここで期待されているのは、
アルファベットの文字列の 'words' は、
'charactors' か 'all' になります。
日本語の場合は、もうすぐリリースされるバージョン4.3から
'all' を選択するべきなので
画面の赤い部分はそのようになっています。
そしてこの値は、
こちらの画面の左下、
管理画面投稿エディタの文字数の部分
文字列カウントの方式を、
単語数ベースなのか、
あるいは文字数ベースなのかを決定するオプションの値として利用されます。
ここまでの話で理解できたと思いますが
現在 WordPress では、言語別機能で利用されるオプションの値は
データベースの中ではなく
各言語の翻訳ファイルの中にあります。
このことを自分は知っているという方は
この中にどれだけ
いらっしゃいますでしょうか。
お手数ですが、
自分は知っている、という方
手を挙げていただけますか?
(メガネをかける)
ゼロですか?
誰もいないですか?
参考になりました。ありがとうございます。
言語別機能の挙動を制御する
オプションの値を
言語ごとの翻訳ファイルに保持して、
読み込ませる
というアイディアが出てきた時は
とても合理的で良いアイディアだな、
と感じました。
しかし、色々なことが出てきて、
すぐにその考えは変わりました。
言語別機能とは、何か?
あらためて説明するまでもないと
思いますが
文字数での抜粋、
ISO-2022-JP でのメールなど、
特定の言語環境でのみ必要な機能で、
WP Multibyte Patch で取り扱って
いるような機能を指します。
日本語圏の人間にはごくごくあたりまえの
存在だと思いますが
ところが、WordPress 本体で言語別機能の取り組みが開始されたのは
2012年、つい3年前です。
WordPress が初めてリリースされたのが
12年前の2003年、
WP Multibyte Patch が初めてリリースされたのが、
8年前、
2007年ですので、
これは非常に遅い対応であるといえます。
具体的には、
こちらの、エディターの文字数ベースのカウントの実装や、
こちらの抜粋関数での、文字数ベース
抜粋での対応などが、
コアでの言語別機能を意識した初めての実装だと思います。
ぼくは、このどちらの実装の時もチケットをみて
リアルタイムで関わっていたのですが、
後々、今に至るまで
影響をおよぼすこととなる、あまり好ましくない実装を
このときは見過ごしていました。
翻訳ファイルがないとオプション値が読み込まれない
これは、データが保存されているのだから
当たり前の話です。
MySQL のデータが消えてしまえば
WordPress サイトが見れなくなるのと同じことです。
このような事態は、めったにあってはならないことですが、
翻訳ファイルに関しては色々なケースで発生します。
ネットワークに繋がらない環境では、翻訳ファイルは手に入りません。
ユーザーが誤って削除してしまうこともあります。
また、そもそも個人ブログなどでは
公開側のインターフェイスが翻訳されている必要がない、
あるいは、一時的に翻訳させたくないケースも少なくありません。
ぼくのサイトでは、翻訳ファイルは管理画面だけにして、
公開側では読み込んでいません。
このように、翻訳ファイルが存在しないという状況が
いろいろあり得るのですが、
そんなとき、機能まで完全に英語版になってしまう、
抜粋がきかなくなってしまう、といったような、
不便で不安定な実装は好ましくありません。
誤って修正された場合、
重要な機能が正しく動作しなくなってしまう。
これは深刻な問題です。
現在、翻訳は、GlotPress という仕組みで
ボランティアによって共同で行われています。
こちらはそのインターフェイスですが、
現在、WordPress 周辺の様々な文字列翻訳が
こちらのシステムで行われており、
WordPress.org のフォーラムの
アカウントさえ持っていれば
どなたでも翻訳に参加することが出来ます。
こちらで行われた翻訳は、自動的に
世界中の WordPress サイトで配信されます。
WordPress の管理画面で、
「新しい翻訳が利用可能です」という通知を
頻繁に見かけると思います。
例えば、こちらのシステムで
新米の翻訳者が、誤って日本語の抜粋カウントを
単語ベースに変えてしまったら
どうなると思いますか?
すぐにネット中が
「WordPress で抜粋が行われなくなった」という
日本人ユーザーの悲鳴でうめつくされることになるかもしれません。
しかし実際は、そこまでひどいことには
ならないと思います。
なぜなら、日本人ユーザーの多くの方が使っている
WP Multibyte Patch が、翻訳ファイルを利用しないで
抜粋カウント方式を文字数ベースに固定する機能がついており
デフォルトで有効となっているからです。
したがって、WP Multibyte Patch を有効にしている方は
とりあえずは、この問題を心配する必要はありません。
その他、使い勝手の問題としては
仕様として知られていない、先ほどゼロだったことからわかるように
誰も知らない仕様です。
理解しにくい。
ユーザーによる編集が困難、などが挙げられます。
Polyglots という WordPress 国際化の公式ページに
この問題についての様々な問題や意見が投稿されているスレッドが有ります。
英語ですが、興味がある方は見てみてください。
こちらには、僕も意見を投稿しています。
主な内容としては、
翻訳ファイルは中身が常に変動して
存在自体が不安定なので
重要な言語機能のオプションがそこにある、ということは
言語別機能の動作の信頼性を損ねている、ということや、
翻訳ファイルに言語別機能のオプション値を保存する実装を廃止して、
翻訳ファイルと言語別機能を完全に分離するべきである、ということなどです。
投稿には書きませんでしたが、
翻訳ファイルに保存しないならば、
言語別のオプションは、どこに保存されるのが望ましいか、という課題があります。
思いつくのは、データベースの中
あるいは、フィルターできる形での値のハードコーディングです。
WP Multibyte Patch は、今後
後者のアプローチで
実験的に取り入れていくかもしれません。
これは、Make.WordPress.org のトップページに使われている
2012年のコミュニティサミットの時の
集合写真です。
前から2列目、赤いベストのマットの右隣
チェックのシャツがネイシンです。
階段の上のほう、右端で、
グレーの帽子にメガネをかけているのがぼくです。
Contact Form 7 の三好さんもいるんですが
どこにいるかわかりますでしょうか。
僕はこのとき以来、2,3年越しでネイシンと
「翻訳ファイル集約主義」の問題点について
やりとりをしていたのですが
それは、冒頭で話した2014年の
バージョン 4.0 の実装で
ひとつのクライマックスを迎えました。
バージョン 4.0 で行われた
翻訳ファイルの存在がある場合に限り、
言語設定ができる、という実装。
これには先程述べた翻訳ファイルがないと
オプション値が読み込まれない、という問題の防止策としての
意図があったように思います。
真意はわかりませんが、しかしこれは明らかな
本末転倒の、誤った実装です。
正しくはこのようになるはずです。
なぜなら、言語設定に合わせて
適切な言語ファイルを読み込むという動作が
言語別機能のひとつに過ぎないからです。
また、これは長年の WordPress の仕様でもありました。
「言語別機能は、翻訳よりも重要である」
英語圏の開発者の多くは、
非英語圏のユーザーにとって言語別機能がいかに大切であるか、ということを
理解していません。
いかにインターフェイスが日本語になっていようとも、
抜粋が機能しなかったり、日本語のメールが文字化けしてしまうようなシステムは
利用したくありません。
逆に、インターフェイスが英語でも、
便利で、日本語の処理に問題がないシステムであったなら、
多くの日本人が利用するでしょう。
そもそも、英語が読める人にとっては
インターフェイスが翻訳されている必要は無いのですから
翻訳とは、オプションで選べる、ピンのようなものであると思います。
こちらのチケットで、4.0 の問題点について
話し合いが行われました。
結果として「翻訳ファイル集約主義」に欠陥があること、
また、言語別機能が翻訳よりも重要であるということを
ネイシンが理解して、受け入れてくれたことは
大きな収穫でした。
そしてその後、4.0以降の言語設定の実装が
次のように変更されました。
WordPress を日本語でインストールする。
日本語の翻訳ファイルを削除。
言語を日本語に設定することができなくなる。
と、ここまでは先ほどの説明と同じです。
次に、wp-config.php に 'WPLANG' 'JA' を加えます。
すると、今度は日本語が選択肢にあらわれて
設定できるようになります。
翻訳ファイルがないので、
インターフェイスは英語のままです。
この状態で英語に設定すると、
今度は WPLANG は不要という注意が出てきます。
WPLANG は実は廃止になったわけではなく、別の役割、
翻訳ファイルがない場合の
フォールバックとして残っています。
また、これは翻訳ファイルの有無にかかわらず、
言語設定を自由に行なえる唯一の方法である、
ということを知っておいてください。
WordPress の i18n の実装で
「翻訳ファイル集約主義」が問題であることについて説明しましたが
もう一つの大きな問題があります。
それは、PHP で使われている
正規表現のライブラリーである、
PCRE の挙動が不安定であり
そのために、一部環境で
マルチバイトの文字列が破壊されてしまうという問題で、
WordPress の世界における大きなマルチバイトのバグの原因となっています。
Perl 互換の正規表現の置換関数で、
空白文字を、エスケープシーケンスである \s が
マルチバイト文字の一部にマッチしてしまい、
文字を破壊して
文字化けを起こすことがありますが、
このようなバグを引き起こすコードが
WordPress のいたるところに潜んでいます。
WordPress では、文字列操作の多くを
Perl 互換の正規表現に依存しているために
この問題が起こります。
解決策として、
U 修飾子を利用する方法があります。
この修飾子を使うと
最初の文字列が、UTF-8 として認識されるようになり
\s がマルチバイトの一部にマッチしてしまうことがなくなります。
しかし、一見理想的に思えるこの解決策には
落とし穴があります。
PCRE U 修飾子の利用には
コンパイル時に UTF-8 サポートのオプションが必要で
それが全てのユーザー環境でコンパイルされているとは
限らないということが
徐々にわかってきました。
つまり、ユーザーの環境においては
この方法はうまくいかないのです。
ただでさえ、PCRE の Unicode property support が
コンパイルされているか否か、
また、そのオプションにより
\s の挙動が異なることまでわかってきました。
これらの詳しい情報に興味がある方は、
こちらのチケットを見てみると良いでしょう。
大変難しい内容ですが、
PHP 開発者の方は読んでみることを
おすすめします。
Unicode property support の挙動に関する PHP のバグは、
なんとこのチケットでのリサーチから発見されました。
発見者は、Robert Chapin さんと、
Andrew Ozz さんです。
この2人は、最重要になる
PCRE library 作者のところまで行き
問題の根源をつきとめました。
この発見は、今まで不明だった
PHP のファイル互換正規表現関数の挙動を知る上で
多くの開発に役に立つものと思われます。
PCRE が絡んだ、文字破壊の最新の解決策のゆくえを知りたい方は、
こちらのチケットを定期的にチェックしてみるといいでしょう。
今のところ、 WordPress コアではこの問題に対する決定的な解決策がないため
チケットは、バグが直されないまま一年以上に渡り保留されていますが
いつかは解決する時が来るでしょう。
WP Multibyte Patch では、WordPress コアでは
直せない PCRE の問題箇所の幾つかを
修正しています。
コアでは直せないものを、なぜ
WP Multibyte Patch で直せるのか。
その秘密は、WP Multibyte Patch では
マルチバイト文字列関数を提供する mbstring が PHP に組み込まれていることを
プラグイン有効化の条件としていることです。
そして、より安全な mbstring 系の関数で
コアの問題のある PCRE 系のコードを置き換えています。
WordPress コアでは、mbstring は
システム要件ではないため
このように、簡単に直すことは出来ません。
このように、プラグインだからこそ直せる問題
というものもあるということです。
最後に、日本語ユーザー全体の課題、
マルチバイト圏ユーザー共通の課題について
話したいと思います
いま、ローカル言語チームが
ローカルパッケージに、独自の言語
特有機能を追加するための自由領域が
制限される方向にあります。
そして、近いうちにほとんどなくなるかもしれないという状況にあります。
WordPress の良い所として、
コンパチビリティの重視が挙げられますが
これは、言い換えれば
一度実装された機能はなかなか覆せないということでもあります。
だからこそ、我々マルチバイト圏のユーザーにとって
WordPress が使いにくくなってしまうような実装が行われないよう
目を光らせていることが大切なのです。
みんなで協力し、日本語についてよく知らないコア開発者の人たちを助けて
WordPress がいつまでも我々マルチバイト圏の
ユーザーにとって使いやすいツールであるように
見守っていけたらと思います。
ご清聴ありがとうございました。
ありがとうございました。
スピーカーは倉石政典さんでした。もう一度拍手をお願いします。