虎哲の gettext 周りも整理しつつ,gettext についての解説を充実させたい。
gettext については大分前に書いたブログ記事がまだ読まれているところをみるに,勉強したい人が意外に多いらしい。
しかし,やりたいこと多すぎるな……。
この描出は,2008年2月17日投稿の旧ブログ記事を再録したものです。長らく更新されていませんので,最新の情報は著者のページからお探し下さい。
本記事の「その1」では、WordPress を題材に gettext のごく基本的な用語や仕組みを説明しました。
gettext の扱い方は、WordPress の運用に限らず柔軟性のあるプログラムを作りたい場合には必須の知識です。プログラム作成者がとくに知っておく必要があるのは、ソースファイルから可訳文字列などを自動抽出して PO ファイルを作る xgettext と msginit コマンドの使い方です。これに加え、WordPress のテーマ作成者・翻訳者は MO ファイルをテーマごとに用意する方法も知っておくと非常に便利です。
xgettext コマンドの使い方
xgettext はソースファイルから可訳文字列やコメントを抽出し、PO ファイルの雛形 (POT: PO Template) となるファイルを作ります。
最も単純な使いかたは、下の通りです。可訳文字列を抽出したいファイルとキーワード関数の名前を "-k" オプションに続けて指定します。ファイルは複数指定できます。gettext の標準ではキーワードは "gettext" となっており、これに従う記法では省略できますが、WordPress (PHP-gettext?) では "__" と "_e" の二つを使うので指定する必要があります。
$ xgettext index.php -k__ -k_e
これを実行すると、カレントディレクトリに messages.po という名前の POT ファイルが作成されます。中身は、PO ファイルと同じ形式ですが、対象言語、翻訳者の名前・連絡先、更新日時など諸々の情報を記すためのヘッダ部分が未定の状態になっています。
出力される POT ファイルの名前は、下の通り "-o" オプションで指定することも出来ます。
$ xgettext index.php -o test.pot -k__ -k_e
ファイルは複数指定できますが、ファイルがたくさんあると毎回入力するのは面倒です。そういう場合、抽出したいファイル名を改行で区切ってテキストファイルに保存しておき、"-f" オプションで読みこませることが出来ます。
$ xgettext -f filelist.txt -k__ -k_e
"-c" オプションに続けて文字列を指定すると、その文字列が含まれているキーワード関数の直前にあるコメントを抽出することが出来ます。下の例では "NOTES:" を含むコメントを抽出します。これは主に特定の可訳文字列に対して、ソースファイルの作成者が補足的な情報を加えるために使われます。
$ xgettext -f ja_filelist.txt -k__ -k_e -cNOTES:
抽出する可訳文字列かコメントのどちらか一方にでも ASCII (英数字等) 以外の文字列が含まれている場合、"--from-code=" オプションでソースファイルの文字コードを指定する必要があります。日本語の場合は euc-jp, shift-jis, utf8 などですが、必ずソースファイルと同じものを指定します。下の例では utf8 (UTF-8) を指定しています。
$ xgettext -f ja_filelist.txt -k__ -k_e -cNOTES: --from-code=utf8
xgettext コマンドで主に使用するオプションは以上です。まとめると下記の通りです。
<dl> <dt>-k (--keyword=)</dt> <dd>キーワード関数の名前を指定する。</dd> <dt>-f (--files-from=)</dt> <dd>入力ファイルをリストから読みこむ。</dd> <dt>-o (--output=)</dt> <dd>出力ファイルの名前を指定する。</dd> <dt>-c (--add-comments=)</dt> <dd>キーワード関数直前にある、指定の文字列を含むコメントを抽出する。</dd> <dt>--from-code=</dt> <dd>ソースファイルの文字コードを指定する。</dd> </dl>msginit コマンドの使い方
msginit は xgettext で作った POT から実際に編集作業に使う PO ファイルを作ります。 使い方は "-l" (または --locale=) オプションに続けて言語コードを、"-i" (または --input=) オプションに続けて POT ファイルを指定します。
$ msginit -l ja -i messages.po
これを実行すると、ヘッダ情報が設定された "[言語コード].po" ファイルが作成されます。例では日本語の "ja.po" です。ここで「不正な複数バイトのシーケンス」といったエラーがでる場合、下記のように抽出元ソースファイルの文字コードまで指定して下さい。(例では UTF-8)
$ msginit -l ja_JP.UTF-8 -i messages.po
テーマ別 MO ファイル
WordPress のテーマが使用する MO ファイルが置かれているディレクトリは、下のように「標準」と「テーマ別」の二箇所あります。
<dl> <dt>標準</dt> <dd>wp-content/languages/</dd> <dt>テーマ別</dt> <dd>wp-content/themes/[テーマ名]/</dd> </dl>こちらの説明では省略しましたが、キーワード関数には第二引数があり、これを省略すると標準の MO ファイルが使用されるようになっています。第二引数には、テキストドメインという、可訳文字列の所属を表わす文字列を指定します。テーマにテキストドメインが設定されていれば、それを指定してテーマ毎の MO ファイルを使用するように出来ます。テーマ別の翻訳ファイルであれば、テーマと一緒に簡単に配布できて便利です。
テーマにテキストドメインを設定するには、テーマのディレクトリ内の "functions.php" というファイルに下の行を追加します (存在しない場合は同名の空ファイルを新規に作成します)。例ではテーマ名を "abc" とします。
<?php load_theme_textdomain('abc'); ?>
こうした上で、下記のキーワード関数で指定された可訳文字列にはテーマディレクトリ内の MO ファイルが適用されます 。"__()" 関数でも同様です。
<?php _e('Translatable string', 'abc'); ?>
2008/2/28 加筆・修正
2008/2/24 修正
この描出は,2008年2月2日投稿の旧ブログ記事を再録したものです。長らく更新されていませんので,最新の情報は著者のページからお探し下さい。
WordPress は、gettext を利用して多言語に対応しています。
WordPress 上の日本語で表示されている見出しやメッセージ類を変更したい場合や、未訳部分を日本語化したい場合などには、gettext に関する多少の知識が必要になります。
本記事では、WordPress を利用していて、日本語化部分を少し修正できればいいという方から、gettext の仕組みをある程度理解したい方までを対象に、段階的に gettext への理解が進むような解説を心がけています。
gettext とは
gettext とは、ソフトウェアの利用者に対して表示される定型文などの言語を、利用者の母国語などに合わせて簡単に翻訳文に差し替えるための仕組みを実現する、ライブラリ (システム側で用意するもの) とツール一式 (利用者側で使用するもの) のことを差します。
WordPress では PHP-gettext というライブラリを利用して、この仕組みを提供しています。
これによって、一般のブログ運用者でも gettext のツールを利用すれば、ソフトウェア内部の仕組みに立ち入らずに割と簡単に翻訳内容を修正することができます。
gettext ツールは UNIX 向けの GNU gettext が主流です。Windows では、PoEdit という直感的に操作できるものもあります (MMRT daily life さんのページで解説されています)。Windows 上で GNU gettext を使用したい場合は、Cygwin を導入するか、移植版を利用することになります。
既存の翻訳を修正したい場合
WordPress Japan で配布されている日本語版 WordPress (ME 2.2.3) を例にとり、既に表示されている日本語文を修正する手順を見ていきます。
(インストール先) wp-content/languages/ に ja.po と ja.mo というファイルがあります。それぞれ拡張子と同じく PO ファイル、MO ファイルと呼ばれており、次のような役割があります。
実際に翻訳内容を修正するためには最低限、PO ファイルを編集し、それを gettext ツールによって MO ファイルへ変換するという作業が必要になります。なお、本記事ではGNU gettext を使って解説していきますが、この基本的な流れはどのツールを利用しても共通です。
PO ファイルの書式
PO ファイルをテキストエディタなどで覗いてみると、このような形式で翻訳前・翻訳後の文が羅列されています。
#: wp-content/themes/abc/index.php:11 msgid "This is a translatable string." msgstr "これが可訳文字列です。"
このうち、重要なのは "msgid" と "msgstr" で始まる二つの行です。プログラムのソースファイル中で翻訳対象として記述された「可訳文字列」(translatable string, 翻訳可能な文字列の意) が msgid の行に抽出されています。翻訳者は msgstr の行で、可訳文字列に対する翻訳後の文字列を記述します。この二つの行は必ず対で、翻訳前後の文字列を表わすようになっています。
"#" で始まる行はコメントです。コメントにはいくつか種類がありますが、いずれも読み手に情報を与えるためのもので、システム上の意味は通常ありません。翻訳上の必要が生じた時に参照します。
WordPress ME の ja.po ファイルには、Default テーマや Classic テーマ、付属のプラグインなどの可訳文字列が抽出されているので、どの英語をどういう日本語に訳しているのか、ということがこのファイルを見れば分かります。念のため ja.po ファイルのバックアップを取り、msgstr で始まる行の文を好きなように書き換えてみても大丈夫です (msgid で始まる行は変更しないで下さい)。
MO ファイルを作る
PO ファイルは翻訳作業を行なうためのファイルです。PO ファイルを書き換えるだけでは、プログラムに新しい翻訳内容は反映されません。修正した翻訳内容を反映させるには、PO ファイルをもとに作成した MO ファイルがプログラム指定の場所に置かれている必要があります。WordPress ME では ja.po と同じ場所に ja.mo というファイルを置きます。
MO ファイルは、 GNU gettext を使う場合、付属の msgfmt というコマンドで作成します。msgfmt は下記の要領で使います。
$ msgfmt -o [作成する MO ファイル名] [PO ファイル名]
WordPress ME の場合、ja.po と同じディレクトリに移動して、下記のように実行します。
$ msgfmt -o ja.mo ja.po
これで修正した PO ファイルにもとづいた MO ファイルが作成され、プログラムに翻訳内容が反映されるようになります。
新しく可訳文字列を指定する
これまでの方法で、すでに用意されている (PO ファイルに抽出されている) 可訳文字列を修正することは出来ます。しかし、プログラム中のある文字列が可訳文字列かどうか、ということは逐一プログラムのソースファイル中で指定する必要があり、これは当該プログラム開発者の翻訳者に対する配慮に依っています。特に WordPress の場合、一般にブログ等として公開されるページデザインの全ては「テーマ」という単位で定義するため、利用したテーマが海外製で多言語化に配慮されていないと、当然ほとんどの部分が元の言語のまま表示されます。
こういう場合は、ソースファイルを修正して目的の文字列を可訳文字列として指定する以外ありません。幸い、WordPress は PHP で作られているので、HTML コードを修正する感覚でこうした作業ができます。可訳文字列の指定は文字列を特定のキーワード関数の引数として指定するだけです。
WordPress で可訳文字列の指定に使用するのは以下の二つのキーワード関数です。
<dl> <dt>_e()</dt> <dd>可訳文字列を標準出力 (echo) する関数。ただ単にその文字列を表示したい時に用いる。関数内で引数になっている文字列の指定には使えない。</dd> <dt>__()</dt> <dd>可訳文字列を戻り値として返す関数。その文字列を別の関数に引数として渡したい時に用いる。単体で使うだけでは何も出力 (表示) されない。</dd> </dl>ここではソースファイル
(インストール先) wp-content/themes/default/index.php
を参考にして、実際にどのように修正すればよいかを説明します。
<div class="entry"> <?php the_content('Read the rest of this entry »'); ?> </div>
これはエントリを出力する the_content() 関数の例です。この関数の第一引数へは、エントリ一覧などで長い文章を省略するときに全文へのリンクになっている、「続きを読む」のような文を指定します。これを可訳文字列に指定したい場合は、別の関数への引数としての指定なので __() 関数を使用します。
<div class="entry"> <?php the_content(__('Read the rest of this entry »')); ?> </div>
これで、__() 関数で指定された可訳文字列が、__() 関数の戻り値として the_content() 関数に渡されることになります。
<h2 class="center">Not Found</h2> <p class="center">Sorry, but you are looking for something that isn't here.</p>
一方、こちらはエントリが見つからなかった場合に表示される文です。これは、PHP 文ではなく単に HTML コードとして書かれています。この場合は単純にそのまま表示される文字列を可訳文字列に置き換えたいだけなので、指定したい箇所を PHP 文にして __e 関数を使用します。
<h2 class="center"><?php _e('Not Found') ?></h2> <p class="center"><?php _e('Sorry, but you are looking for something that isn't here.') ?></p>
あとは、下記のように PO ファイルでこれらの可訳文字列に対応する翻訳文を設定し、MO ファイルを作成すればよいです。後述するように gettext には、ソースファイル中の可訳文字列を自動的に抽出して PO ファイルの雛形を作成するコマンドがありますが、ここでは簡単に効果を確かめるため、既存の ja.po ファイルに手入力で追記する例を示します。このようにしても、各可訳文字列に対する翻訳文が適用されます。msgid に指定する文字列は、キーワード関数に渡した文字列と同じにしなくてはなりません (msgid は当の可訳文字列を識別する ID という意味です)。
# test msgid "Read the rest of this entry »" msgstr "続きを読む »" msgid "Not Found" msgstr "見つかりません" msgid "Sorry, but you are looking for something that isn't here." msgstr "ごめんなさい。お探しのものはここにはありません。"
ソースファイルから可訳文字列や特定のコメントを抽出する xgettext コマンドの使い方、テーマ別に PO ファイルを用意する方法などの解説は「その2」に続きます。
2008/2/28 修正