当サイト、Codex 日本語版は今後積極的な更新は行わない予定です。後継となる新ユーザーマニュアルは、https://ja.wordpress.org/support/ にあります。
万が一、当サイトで重大な問題を発見した際などは、フォーラムWordSlack #docs チャンネルでお知らせください。</p>

I18n for WordPress Developers

提供: WordPress Codex 日本語版
2010年2月20日 (土) 09:49時点におけるMizuno (トーク | 投稿記録)による版 (翻訳する文字列をマークする: まで翻訳)

移動先: 案内検索

このページ「I18n for WordPress Developers」は未翻訳です。和訳や日本語情報を加筆してくださる協力者を求めています

国際化とは

I18n は、internationalization、すなわちアプリケーションを翻訳可能にするプロセスのことをいいます。WordPress では、決まった方法で翻訳されるべき文字列をマークすることを意味します。I と n の間に 18 文字あるため、これを i18n と呼びます。

Gettext 入門

WordPress では、gettext ライブラリおよびツールを使用して国際化します。

翻訳可能文字列

アプリケーションで文字列を翻訳可能にするには、元の文字列を __ 関数コールで囲います。

$hello = __("Hello, dear user!");

文字列をブラウザーに表示する場合は、_e 関数を使います。

_e("Your Ad here")

POT ファイル

ソースファイルで文字列をマークしたら、xgettext という gettext ユーティリティを使用して文字列を抽出し、テンプレート翻訳 POT ファイルを構築します。以下は、POT ファイルのエントリの例です。

#: wp-admin/admin-header.php:49
msgid "Sign Out"
msgstr ""

PO ファイル

翻訳者は WordPress POT ファイルを受け取り、msgstr セクションを自分の言語に翻訳します。出力は PO ファイルです。POT ファイルとフォーマットは同じですが、翻訳されていて、特定のヘッダが異なります。

MO ファイル

翻訳済み PO ファイルから MO ファイルを構築します。このファイルは、すべての元の文字列と翻訳を含み、高速に翻訳を抽出するのに適したバイナリファイルです。msgfmt ツールを使用して変換します。

テキストドメイン

1 つのアプリケーションに、複数の巨大な論理翻訳モジュールを使用し、それらに異なる MO ファイルを使用する必要があるかもしれません。ドメインは、各モジュールをハンドルし、それぞれ異なる MO ファイルを持ちます。テーマの翻訳とプラグインの翻訳は、異なるドメインになります。

gettext に関して詳しく知りたい方は、gettext online manual を参照することをおすすめします。

翻訳する文字列をマークする

翻訳する文字列は、特別な関数のいずれかを呼び出すように囲います。最もよく用いられるのは、__() です。この関数は、引数の訳を返します。

echo "<h2>".__('Blog Options')."</h2>";

別の例は、_e() です。この関数は引数の訳を出力します。echo __('Using this option you will make a fortune!'); と書く代わりに、短縮した _e('Using this option you will make a fortune!'); を使用できます。

プレースホルダ

echo "We deleted $count spams."

この行はどうやって国際化しますか?試してみましょう。

_e("We deleted $count spams.");

これは動作しません。翻訳する文字列はソースから抽出されるので、We deleted $count spams. というフレーズの翻訳は上手くいくでしょう。しかし、この例では、_eWe deleted 49494 spams. のような引数を伴って呼び出され、gettext は適切な翻訳を見つけることができず、引数 We deleted 49494 spams. をそのまま返します。残念ながら、適切に翻訳されません。

解決法は、printf やその類似の関数を使うことです。printfsprintf が特に役立ちます。スパムを数えるプログラムの適切な解決は、以下のようになります。

printf(__("We deleted %d spams."), $count);

ここでは翻訳する文字列は、テンプレート We deleted %d spams. (ソースでも実行時でも同じ)であることに注意してください。

複数のプレースホルダがある場合は、argument swapping を許可してください。

printf(__("Your city is %1$s, and your zip code is %2$s."));

ここでは原著者の文字列では都市と郵便番号の順が示されています。しかし、最初に郵便番号、次に都市の順のほうが適切な国もあるでしょう。%s を使用してしまうと、翻訳者が順序を入れ替えることができなくなります。

複数

スパムの例 printf(__("We deleted %d spams."), $count); に戻りましょう。スパムを 1 つだけ削除した場合はどうなるでしょう。出力は We deleted 1 spams. のようになり、正しい英語ではありません。また他の言語でも正しくないでしょう。

WordPress では _n 関数を使うことができます。

printf(_n("We deleted %d spam.", "We deleted %d spams.", $count), $count);

_n は、3 つの引数を取ります。

  • singular — 単数形
  • plural — 複数形
  • count — 単数形と複数形のどちらを用いるかを決定する数。(2 より多い形を持つ言語があります)

この関数の戻り値は、与えられた数に対応する翻訳されたフォームになります。

文脈による曖昧性回避

ある用語が、複数の文脈で用いられ、英語では同じ単語だが、他の言語では別の単語に翻訳すべきことがあります。例えば、単語 Post は、動詞 (ここをクリックしてコメントを投稿する) としても名詞 (この投稿を編集する) としても使用できます。このような場合、_x() 関数を使用すべきです。この関数は __() に似ていますが、文脈を第二引数にします。

if ( false === $commenttxt ) $commenttxt = _x( 'Comment', 'noun' );
if ( false === $trackbacktxt ) $trackbacktxt = __( 'Trackback' );
if ( false === $pingbacktxt ) $pingbacktxt = __( 'Pingback' );
...
// some other place in the code
echo _x('Comment', 'column name');

こうすることで、元バージョンの文字列 Comment を、翻訳者は、異なる文脈の 2 つの Comment 文字列とみなすことができます。

説明

__('g:i:s a') のような文字列を翻訳者がどう訳していいか分かると思いますか? この場合、ソースコードにコメントを追加できます。コメントは、translators: という語で始まり、gettext を呼び出す直前の PHP コメントである必要があります。以下に例を示します。

/* translators: draft saved date format, see http://php.net/date */
$draft_saved_date_format = __('g:i:s a');

translators: コメントを追加することで、翻訳者宛にメッセージを書くことができ、翻訳者が文字列がどんなものかを知ることができます。

改行文字

Gettext は、翻訳する文字列に \r (ASCII code: 13) を好みません。 \r の代わりに \n を使用してください。

JavaScript ファイルを処理する

Best Practices

Until we gather some WordPress-specific examples, use your time to read the short, but excellent article in the gettext manual. Summarized, it looks like this:

  • Decent English style — minimize slang and abbreviations.
  • Entire sentences — in most languages word order is different than that in English.
  • Split at paragraphs — merge related sentences, but do not include whole page of text in one string.
  • Use format strings instead of string concatenation — sprintf(__('Replace %s with %s'), $a, $b); is always better than __('Replace ').$a.__(' with ').$b; .
  • Avoid unusual markup and unusual control characters — do not include tags that surround your text and do not leave URLs for translation, unless they could have version in another language.

I18n for theme and plugin developers

Choosing and loading a domain

The text domain is a unique identifier, which makes sure WordPress can distinguish between all loaded translations. Using the basename of your plugin is always a good choice.

Example: if your plugin is a single file called shareadraft.php or it is contained in a folder called shareadraft the best domain name you can choose is shareadraft. In case of a theme — choose the directory name.

The domain name is also used to form the name of the MO file with your plugins' translations. You can load them by invoking:

load_plugin_textdomain( $domain, $path_from_abspath, $path_from_plugins_folder )

as early as the init action.

Example:

$plugin_dir = basename(dirname(__FILE__));
load_plugin_textdomain( 'myplugin', 'wp-content/plugins/' . $plugin_dir, $plugin_dir );

This call tries to load myplugin.locale.mo from your plugin's base directory. The locale consistes of a language code and country code separated by an underscore. (For more information about language and country codes, see Installing WordPress in Your Language.)

The second and third parameters are present because of a change that occurred in WordPress 2.6. For versions lower than 2.6, the second parameter should be the directory containing the .mo file, relative to ABSPATH.

For WordPress 2.6 and up, the third parameter is the directory containing the .mo file, relative to the plugins directory. (Thus, if you plugin doesn't need compatibility with older versions of WordPress, you can leave the second parameter blank.)

For themes the process is surprisingly similar:

load_theme_textdomain(domain-name);

Put this call in your functions.php and it will search your theme directory for locale.mo and load it (where locale is the current language, i.e. pt_BR.mo).

I18n for widgets developed on 2.8+

WordPress 2.8+ uses a new widget API, that only requires the widget developer to extend the standard widget class and some of it's functions. With this new API there is no init function. After the widget is coded using the widget(), form(), and update() functions, the widget must be registered. The text-domain is then loaded after the widget is registered.

Example:

// register FooWidget widget
add_action('widgets_init', create_function(, 'return register_widget("FooWidget");'));
$plugin_dir = basename(dirname(__FILE__));
load_plugin_textdomain( 'FooWidget', 'wp-content/plugins/' . $plugin_dir, $plugin_dir );

This example registers a widget named FooWidget, then sets the plugin directory variable and attempts to load the FooWidget-locale.po file.

Marking strings in themes and plugins

All the rules from above apply here, but there is one more. The additional rule states that you must add your domain as an argument to every __, _e, _c and __ngettext call, otherwise your translations won't work.

Examples:

  • __('String') should become __('String', 'domain')
  • _e('String') should become _e('String', 'domain')
  • __ngettext('String', 'Strings', $c) should become __ngettext('String', 'Strings', $c, 'domain')

Adding the domain by hand is a burden and that's why you can do it automatically:

  • If your plugin is registered in the official repository, go to your Admin page there and scroll to Add Domain to Gettext Calls.

Otherwise:

php add-textdomain.php -i domain phpfile phpfile ...

After it's done, the domain will be added to all gettext calls in the files.

Generating a POT file

You remember the POT file is the one you need to hand to translators, so that they can do their work, don't you?

Once that is in place, there are a couple of ways to generate a POT file for your plugin:

  1. If your plugin is registered in the official repository, go to your Admin page there and scroll to Generate POT file.
  2. If your plugin is not in the repository, you can checkout the wordpress-i18n tools directory from SVN (see Using Subversion to learn about SVN) and then run the makepot.php script like this:
php makepot.php wp-plugin your-plugin-directory

You need the gettext (GNU Internationalization utilities) package to be installed in your server before you can run the above command After it's finished you should see the POT file in the current directory.

It is a good idea to offer the POT file along with your plugin, so that translators won't have to ask you specifically about it.

Also, if you add a line like this to your plugin header, WordPress should internationalize your plugin meta-data when it displays your plugin in the admin screens: Text Domain: your-text-domain

Resources

Localizing WordPress Themes and Plugins

最新英語版: WordPress Codex » I18n_for_WordPress_Developers最新版との差分