WordPress の国際化について調べてみましたので、覚えたことを本稿にまとめておきます。基本的に本稿末尾にまとめてある参考サイトと同様の手順ですが、自分なりに引っかかった部分があったので、そのあたりを補足しながらまとめました。
事前の知識
WordPress での国際化について、全体的な流れは次のような感じになります。
- 環境の準備
- ソースコードの国際化
- .pot ファイルの作成
- .po ファイルの翻訳
- .mo ファイルのコンパイル
環境の準備は最初だけですね。ソースコードの国際化というのは決められた関数で文字列を出力することと、言語ファイルの読み込み設定の追加です。.pot、.po、.mo について詳しくは後述しますが、gettext という翻訳ライブラリの仕様に基づく構成ファイルです。
WordPress では多言語化の為に「gettext」という国際化とローカリゼーションの為のライブラリを利用します。gettext では、まずはアプリケーション中で翻訳が必要な箇所について、あらかじめ決められた構文で記述しています。そして出来上がったソースコードに対して、ツールを使って「.pot」という国際化の為のテンプレートファイルを自動作成します。この .pot ファイルを元に、各言語に翻訳した 「.po」ファイルを準備し、出来上がった po ファイルを「.mo」というバイナリファイルにコンパイルしてアプリケーションに組み込むことで、翻訳が適用されるようになります。
- .pot — 翻訳するための元となるテンプレート
- .po — 翻訳されたファイル
- .mo — .po ファイルをコンパイルしたバイナリ。これが実際の表示に利用される
なお、gettext のこのような仕組みは、WordPress や PHP だけでなく、その他多くのプログラミング環境で提供され、多くのプロダクトで実際に利用されています。また、WordPress では gettext を少し拡張し、より便利に利用できるようになっています。
環境の準備
まず環境を準備します。次の2つの環境については事前に整えておいてください。
- Xcode (最新版) — https://itunes.apple.com/jp/app/xcode/id497799835
- Homebrew — http://mxcl.github.io/homebrew/
gettext のインストール
gettext 環境をインストールします。Homebrewのインストールが完了してから、次のコマンドでインストールしてください。
1 2 |
$ brew install gettext $ brew link gettext --force |
wordpress-i18n tools の準備
WordPressでは国際化の為に gettext を拡張する「wordpress-i18n tools」というツールがコチラで Subversion のリポジトリとして配布されています。これをあなたの環境にダウンロードしてください。場所は基本的にどこに置いておいても構いませんが、ここではユーザーのホームディレクトリに「wp-i18n」という名前のディレクトリを作って準備します。
1 2 3 |
$ cd ~ $ mkdir wp-i18n $ svn co http://i18n.svn.wordpress.org/tools/trunk/ ./wp-i18n |
ソースコードの国際化
ソースコードで国際化したい箇所全てを、WordPress に準備されている国際化の為の関数を使った記述に変更します。例えば次のように HTML 上で「タイトル:」と記述した箇所があるとします。
1 2 3 4 5 |
<p> <label>タイトル: <input name="title" type="text" value="<?php echo $title ?>" /> </label> </p> |
これを次のように変更します。
1 2 3 4 5 |
<p> <label><?php _e( 'Title:', 'mytextdomain' ) ?> <input name="title" type="text" value="<?php echo $title ?>" /> </label> </p> |
2行目を変更しています。関数「_e()」は、翻訳されたテキストを echo する関数です。第1引数が、翻訳のソースとなる文字列です。ある言語の翻訳ファイルが用意されていない時にはこの文字列がそのまま表示されることもあり、一般に英語で記述します。
第2引数の「mytextdomain」は「テキストドメイン」を指定しています。テキストドメインについては後述します。
このような記法で、ソースコード上での翻訳したい箇所をラップして記述していきます。
WordPress に用意されている関数は次の通りです:
__(), _e(), _n(), _x(), _ex(), _nx(), esc_attr__(), esc_attr_e(), esc_attr_x(), esc_html__(), esc_html_e(),esc_html_x(), _n_noop(), _nx_noop()
「__()」が基本で、翻訳テキストを取得します。たくさんあって難しいように見えますが、関数名が意味のある記号の集合として定義されているので、その意味を知るのは意外に簡単です。
- 無印 — ローカライズされた文字列をそのまま返す。
- e — 文字列を echo する
- n — 単数形・複数形の違いを扱う
- x — テキストの文脈を指定する
- esc_attr — HTML 属性としてエスケープする
- esc_html — HTML テキストとしてエスケープする
- noop — 翻訳テキストされたテキストではなく、遅延評価するための情報を返す
「__()」はプレーンな翻訳テキストをそのまま返します。e が付く「_e()」などは、翻訳文字列を echo します。n が付いたものは、数量について単数と複数で異なる記述が必要な言語のサポートです。x が付いたものは、元の言語では同じ記述でも文脈によって意味合いの異なる文字列について、文脈(コンテキスト)を与えて正しく翻訳できるようなサポートが付いたものです。esc_attr、esc_html は文字通りの意味合いです。noop がついたものは遅延評価される形式で値を返します。
noop については分かり難いかも知れませんが、他の関数はコールしたその場で評価されて翻訳テキストを返すのに対して、noop 関数はその場では翻訳テキストを得るための情報のみを返すようになっています。これによって、場合によって幾つかの文字列の切り替えが必要な時に、必要なケースに対応する翻訳テキストのみを取得できる方法を提供します。
テンプレート中、ソースコード中など、翻訳が必要な箇所の全て上記の関数でラップしてください。
テキストドメイン
上の例の第2引数のようにして、全ての関数で、「テキストドメイン」と呼ばれる識別子を指定できます。
テキストドメインとは、そのテキストの意味的な所属を表す識別子です。文字列が同じでも、例えばプラグインやテーマによって、その翻訳が異なることもあります。それらを識別する為に、gettext ではその文字列が所属する意味の範囲(ドメイン)を、テキストドメインと呼ぶ識別子で指定することが出来ます。
WordPress では、プラグインやテーマ毎に、固有のテキストドメインを指定して管理します。なお、テキストドメインは分かり易さのために、一般にプラグインやテーマの名称と一致させます。
テキストドメインを読み込む
プラグインやテーマの初期化時に、テキストドメインを読み込みます。概ね次のような記述になるでしょう。
1 2 3 4 5 6 7 8 9 |
// プラグインの場合 add_action( 'plugin_loaded', function() { load_plugin_textdomain( 'mytextdomain', false, 'myplugin/languages'); } ); //テーマの場合 add_action( 'after_setup_theme', function () { load_theme_textdomain( 'mytextdomain', get_template_directory() . '/languages' ); } ); |
いずれの場合も第1引数はテキストドメイン名です。
load_plugin_textdomain() の第2引数は非推奨となったので利用しません。第3引数は、moファイルが置かれた場所で、wp-content/plugins/ 以下の相対パスで指定します。
load_theme_textdomain() の第2引数はテーマの mo ファイルが置かれた場所です。フルパスで指定します。
.pot ファイルの生成
ソースコード上の国際化の準備が整ったら、wordpress-i18n tools に含まれる「makepot.php」スクリプトを使って .pot ファイルを生成します。プラグインを例に説明します。
コンソールを開いて、.pot ファイルを作成したいプラグインのディレクトリまで移動します。そして言語リソースを納めるための languages ディレクトリを作成し、そして makepot.php を実行します。
1 2 3 |
$ cd myplugin $ mkdir languages $ php ~/wp-i18n/makepot.php wp-plugin . ./languages/mytextdomain.pot |
php に先ほど svn コマンドで落とした wp-i18n ディレクトリの中に含まれる makepot.php を与えて実行します。第1引数「wp-plugin」は .pot ファイルの生成タイプです。プラグインなら「wp-plugin」、テーマなら「wp-theme」を設定します。第2引数は生成したいプラグインのディレクトリを指定します。例ではそのプラグインのディレクトリに居ますので、現在ディレクトリを示す「.」を指定しています。そして第3引数に出力先を与えます。ここでは、作成したばかりの「languages」ディレクトリの中に、「mytextdomain.pot」というファイル名で生成する指定としています。ここでのファイル名は、テキストドメインに一致させてください。
完了すると次のような .pot ファイルが、languages ディレクトリに作成されている筈です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# Copyright (C) 2013 WP Over Network # This file is distributed under the same license as the WP Over Network package. msgid "" msgstr "" "Project-Id-Version: WP Over Network 0.2.1.0\n" "Report-Msgid-Bugs-To: http://wordpress.org/tag/wp_over_network\n" "POT-Creation-Date: 2013-05-25 05:44:51+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "PO-Revision-Date: 2013-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" #: WPONW_RecentPostsWidget.php:17 msgid "The most recent posts on your network" msgstr "" #: WPONW_RecentPostsWidget.php:19 WPONW_RecentPostsWidget.php:44 msgid "Recent Posts over Network" msgstr "" #: templates/widget-form.php:2 msgid "Title:" msgstr "" #: templates/widget-form.php:6 msgid "Number of posts to show:" msgstr "" #: templates/widget-form.php:11 ... 以下略... |
以上はプラグインでの例です。
テーマの場合、テーマのディレクトリに同じく languages ディレクトリを作成して管理するのが良いかと思います。なお、.po や .mo のファイル名は、「{ロケール名}.po」といったように、ロケール名だけをファイル名とします(.pot はテンプレートなので適当で良いでしょう)。makepot.php 実行時のファイルの生成タイプは「wp-theme」とします。
余談ですが、今回参考にさせて頂いたこちらのイケメン記事によると PHP5.4 ではエラーが出まくるそうですので、そこは適宜対応してください。またこちらの記事には、各コマンドのエイリアスの作成方法など、よりイケメンになるための手法も紹介されていますので、イケメンな方はどんどん楽しちゃってください。本稿では基本のみにとどめます。それから、プラグインの時ですが、プラグインを納めているディレクトリ名と同名のファイルがディレクトリ内の存在しないと、PHP の Warning が出力されましたのでご注意ください。おそらくディレクトリ名と同じ名前のプラグインの本体ファイルがディレクトリ内にあるもの、という想定で makepot.php が実装されているのかな、と思います。
.po ファイルの翻訳
.pot ファイルから日本語訳の入った .po ファイルを作成します。
まず、前節で作成した .pot ファイルを複製し、例えば日本語の場合、ファイル名を「mytextdomain-ja.po」とします。テキストドメイン名+ハイフン+言語のロケール(日本語は ja)+拡張子です。拡張子は「.po」としてください。
翻訳はそのまま .po ファイルをテキストエディタで編集することが出来ます。他にも次のような翻訳支援アプリケーションを使って編集することもできますが、ここでの解説は割愛します。
- Poedit — http://sourceforge.jp/projects/sfnet_poedit/
- Google Translator Toolkit — http://translate.google.com/toolkit/
.mo ファイルのコンパイル
gettext のコマンド「msgfmt」を使って .po ファイルを .mo ファイルにコンパイルします。.po が保存されているディレクトリに移動して、msgfmt コマンドを実行します。
1 2 |
$ cd languages $ msgfmt -o mytextdomain-ja.mo mytextdomain-ja.po |
-o オプションで出力ファイル名を指定し、同じファイル名で拡張子だけ変更した .mo ファイルを出力させています。
もしかしたらエラーが出るかも知れませんが、エラーメッセージを見て適宜対処できると思います。
.mo ファイルへのコンパイルに成功したら、ファイルをアップロードしてみましょう。ソースコード中で _e() やその他の国際化関数で出力していた文字列が、日本語として表示されていることをお祈りいたします!
以上です。
参考サイト
本稿をまとめるにあたって以下のページの情報を参考にさせて頂きました。ありがとうございます!
- 「イケメンのためのWordPress翻訳環境構築方法」 @firegoby
- 「I18n for WordPress Developers」@WordPress.org
- 「PHP/WordPress で国際化対応のコードを書く」@Hetarena.com
とくにイケメン先生のサイトは簡潔で分かり易かったですね。いつもありがとうございます!