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

「I18n for WordPress Developers」の版間の差分

提供: WordPress Codex 日本語版
移動先: 案内検索
(2 Gettext 入門: まで翻訳)
(POT ファイルの生成)
 
(5人の利用者による、間の9版が非表示)
1行目: 1行目:
{{NeedTrans}}
+
[https://developer.wordpress.org/plugin/internationalization/how-to-internationalize-your-plugin/ plugin internationalization documentation] はこちらにあります(英語) [https://developer.wordpress.org/plugins/ Plugin Developer Handbook]
 +
 
 +
[https://developer.wordpress.org/plugin/internationalization/localization/ plugin localization documentation] はこちらにあります(英語)[https://developer.wordpress.org/plugins/ Plugin Developer Handbook]
 +
 
 +
[https://developer.wordpress.org/theme/functionality/internationalization/ theme internationalization documentation] はこちらにあります(英語)[https://developer.wordpress.org/themes/getting-started/ Theme Developer Handbook]
 +
 
 +
[https://developer.wordpress.org/theme/functionality/localization/ theme localization documentation] はこちらにあります(英語)[https://developer.wordpress.org/themes/getting-started/ Theme Developer Handbook]
 +
 
 +
 
 
== 国際化とは<!--What is I18n?--> ==
 
== 国際化とは<!--What is I18n?--> ==
 
I18n は、''internationalization''、すなわちアプリケーションを翻訳可能にするプロセスのことをいいます。WordPress では、決まった方法で翻訳されるべき文字列をマークすることを意味します。I と n の間に 18 文字あるため、これを i18n と呼びます。
 
I18n は、''internationalization''、すなわちアプリケーションを翻訳可能にするプロセスのことをいいます。WordPress では、決まった方法で翻訳されるべき文字列をマークすることを意味します。I と n の間に 18 文字あるため、これを i18n と呼びます。
26行目: 34行目:
 
=== MO ファイル<!--MO files--> ===
 
=== MO ファイル<!--MO files--> ===
 
翻訳済み <tt>PO</tt> ファイルから <tt>MO</tt> ファイルを構築します。このファイルは、すべての元の文字列と翻訳を含み、高速に翻訳を抽出するのに適したバイナリファイルです。<tt>msgfmt</tt> ツールを使用して変換します。
 
翻訳済み <tt>PO</tt> ファイルから <tt>MO</tt> ファイルを構築します。このファイルは、すべての元の文字列と翻訳を含み、高速に翻訳を抽出するのに適したバイナリファイルです。<tt>msgfmt</tt> ツールを使用して変換します。
 +
 +
典型的な <tt>msgfmt</tt> コマンドは、<tt>msgfmt -o filename.mo filename.po</tt> です。
 +
 +
fたくさんの <tt>PO</tt> ファイルを一度に変換するために、バッチ処理を実行することができます。例えば、以下のように <tt>bash</tt> コマンドを使用します。
 +
 +
<pre>
 +
# PO ファイルを探し、それぞれに msgfmt を実行し、出力を MO にリネームする
 +
for file in `find . -name "*.po"` ; do msgfmt -o `echo $file | sed s/\.po/\.mo/` $file ; done
 +
</pre>
  
 
=== テキストドメイン<!--Text Domains--> ===
 
=== テキストドメイン<!--Text Domains--> ===
 
1 つのアプリケーションに、複数の巨大な論理翻訳モジュールを使用し、それらに異なる <tt>MO</tt> ファイルを使用する必要があるかもしれません。ドメインは、各モジュールをハンドルし、それぞれ異なる <tt>MO</tt> ファイルを持ちます。テーマの翻訳とプラグインの翻訳は、異なるドメインになります。
 
1 つのアプリケーションに、複数の巨大な論理翻訳モジュールを使用し、それらに異なる <tt>MO</tt> ファイルを使用する必要があるかもしれません。ドメインは、各モジュールをハンドルし、それぞれ異なる <tt>MO</tt> ファイルを持ちます。テーマの翻訳とプラグインの翻訳は、異なるドメインになります。
  
If you want to get a broader and deeper view of gettext, we recommend you the [http://www.gnu.org/software/gettext/manual/html_node/ gettext online manual].
+
gettext に関して詳しく知りたい方は、[http://www.gnu.org/software/gettext/manual/html_node/ gettext online manual] を参照することをおすすめします。
  
== Marking Strings for Translation ==
+
== 翻訳する文字列をマークする<!--Marking Strings for Translation--> ==
The strings for translation are wrapped in a call to one of a set of special functions. The most commonly used one is <tt>__()</tt>. It just returns the translation of its argument:
+
翻訳する文字列は、特別な関数のいずれかを呼び出すように囲います。最もよく用いられるのは、<tt>__()</tt> です。この関数は、引数の訳を返します。
 
<pre>echo "<h2>".__('Blog Options')."</h2>";</pre>
 
<pre>echo "<h2>".__('Blog Options')."</h2>";</pre>
Another simple one is <tt>_e()</tt>, which outputs the translation of its argument. Instead of writing <tt>echo __('Using this option you will make a fortune!');</tt> you can use the shorter <tt>_e('Using this option you will make a fortune!');</tt>
+
別の例は、<tt>_e()</tt> です。この関数は引数の訳を出力します。<tt>echo __('Using this option you will make a fortune!');</tt> と書く代わりに、短縮した <tt>_e('Using this option you will make a fortune!');</tt> を使用できます。
  
=== Placeholders ===
+
=== プレースホルダ<!--Placeholders--> ===
 
<pre>echo "We deleted $count spams."</pre>
 
<pre>echo "We deleted $count spams."</pre>
How would you i18n this line? Let's give it a try together:
+
この行はどうやって国際化しますか?試してみましょう。
 
<pre>_e("We deleted $count spams.");</pre>
 
<pre>_e("We deleted $count spams.");</pre>
It won't work! Remember, the strings for translation are extracted from the sources, so the translators will see work on the phrase: ''We deleted $count spams.''. However in the application <tt>_e</tt> will be called with an argument like ''We deleted 49494 spams.'' and <tt>gettext</tt> won't find a suitable translation of this one and will return its argument: ''We deleted 49494 spams.''. Unfortunately, it isn't translated correctly.
+
これは動作しません。翻訳する文字列はソースから抽出されるので、''We deleted $count spams.'' というフレーズの翻訳は上手くいくでしょう。しかし、この例では、<tt>_e</tt> ''We deleted 49494 spams.'' のような引数を伴って呼び出され、<tt>gettext</tt> は適切な翻訳を見つけることができず、引数 ''We deleted 49494 spams.'' をそのまま返します。残念ながら、適切に翻訳されません。
  
The solution is to use the <tt>printf</tt> family of functions. Especially helpful are [http://php.net/printf printf] and [http://php.net/sprintf sprintf]. Here is what the right solution of the spams count problem will look like:
+
解決法は、<tt>printf</tt> やその類似の関数を使うことです。[http://php.net/printf printf] [http://php.net/sprintf sprintf] が特に役立ちます。スパムを数えるプログラムの適切な解決は、以下のようになります。
 
<pre>printf(__("We deleted %d spams."), $count);</pre>
 
<pre>printf(__("We deleted %d spams."), $count);</pre>
Notice that here the string for translation is just the template ''We deleted %d spams.'', which is the same both in the source and at run-time.
+
ここでは翻訳する文字列は、テンプレート ''We deleted %d spams.'' (ソースでも実行時でも同じ)であることに注意してください。
  
If you have more than one placeholders, please allow [http://php.net/sprintf#id3677438 argument swapping].
+
複数のプレースホルダがある場合は、[http://php.net/sprintf#id3677438 argument swapping] を推奨します。
<pre>printf(__("Your city is %1$s, and your zip code is %2$s."));</pre>
+
<pre>printf(__("Your city is %1$s, and your zip code is %2$s."), $city, $zipcode);</pre>
Here the original author of the string implied an order of the city and zip code. However in some countries it would be more suitable to list the zip first and city second. If you had used <tt>%s</tt> you wouldn't have given the translator the opportunity to swap them.
+
ここでは都市名の後に郵便番号が表示されています。しかし、最初に郵便番号、次に都市の順のほうが適切な言語もあるでしょう。上の例のように <tt>%s</tt> 接頭辞を使用することで、対処可能になります。翻訳は、以下のようにすることができます。
 +
<pre>printf(__("Your zip code is %2$s, and your city is %1$s."), $city, $zipcode);</pre>
 +
(訳注: 実際には printf の中身ではなく .po ファイルで順序を変える --[[利用者:Mizuno|Mizuno]] 2010年4月12日 (月) 05:30 (UTC))
  
=== Plurals ===
+
=== 複数<!--Plurals--> ===
Let's get back to the spams example: <tt>printf(__("We deleted %d spams."), $count);</tt>. What if we delete only one spam? The output will be: ''We deleted 1 spams.'', which is definitely not correct English, and probably any other language.
+
スパムの例 <tt>printf(__("We deleted %d spams."), $count);</tt> に戻りましょう。スパムを 1 つだけ削除した場合はどうなるでしょう。出力は ''We deleted 1 spams.'' のようになり、正しい英語ではありません。また他の言語でも正しくないでしょう。
  
In WordPress you can use the <tt>_n</tt> function.
+
WordPress では <tt>_n</tt> 関数を使うことができます。
 
<pre>printf(_n("We deleted %d spam.", "We deleted %d spams.", $count), $count);</pre>
 
<pre>printf(_n("We deleted %d spam.", "We deleted %d spams.", $count), $count);</pre>
<tt>_n</tt> accepts 3 arguments:
+
<tt>_n</tt> は、3 つの引数を取ります。
* singular &mdash; the singular form of the string
+
* singular &mdash; 単数形
* plural &mdash; the plural form of the string
+
* plural &mdash; 複数形
* count &mdash; the number of objects, which will determine if the singular or the plural form to be returned (there are languages, which have far more than 2 forms)
+
* count &mdash; 単数形と複数形のどちらを用いるかを決定する数。(2 より多い形を持つ言語があります)
The return value of the functions is the correct translated form, corresponding to the given count.
+
この関数の戻り値は、与えられた数に対応する翻訳されたフォームになります。
  
=== Disambiguation by context ===
+
<div id=“Disambiguation_by_context">
 +
=== 文脈による曖昧性回避 ===
 +
</div>
  
Sometimes one term is used in several contexts and although it is one and the same word in English it has to be translated differently in other languages. For example the word Post can be used both as a verb (Click here to post your comment) and as a noun (Edit this post). In such cases the <tt>_x()</tt> function should be used. It is similar to <tt>__()</tt>, but it has an additional second argument -- the context:
+
ある用語が、複数の文脈で用いられ、英語では同じ単語だが、他の言語では別の単語に翻訳すべきことがあります。例えば、単語 Post は、動詞 (ここをクリックしてコメントを投稿する) としても名詞 (この投稿を編集する) としても使用できます。このような場合、<tt>_x()</tt> 関数を使用すべきです。この関数は <tt>__()</tt> に似ていますが、文脈を第二引数にします。
 
<pre>if ( false === $commenttxt ) $commenttxt = _x( 'Comment', 'noun' );
 
<pre>if ( false === $commenttxt ) $commenttxt = _x( 'Comment', 'noun' );
 
if ( false === $trackbacktxt ) $trackbacktxt = __( 'Trackback' );
 
if ( false === $trackbacktxt ) $trackbacktxt = __( 'Trackback' );
72行目: 93行目:
 
echo _x('Comment', 'column name');</pre>
 
echo _x('Comment', 'column name');</pre>
  
Using this method in both cases we will get the string Comment for the original version, but the translators will see two Comment strings for translation, each in the different contexts.
+
こうすることで、元バージョンの文字列 Comment を、翻訳者は、異なる文脈の 2 つの Comment 文字列とみなすことができます。
  
=== Descriptions ===
+
=== 説明<!--Descriptions--> ===
Do you think translators will know how to translate a string like: <tt>__('g:i:s a')</tt>? In this case you can add a clarifying comment in the source code. It has to start with the words <tt>translators:</tt> and to be the last PHP comment before the gettext call. Here is an example:
+
<tt>__('g:i:s a')</tt> のような文字列を翻訳者がどう訳していいか分かると思いますか? この場合、ソースコードにコメントを追加できます。コメントは、<tt>translators:</tt> という語で始まり、gettext を呼び出す直前の PHP コメントである必要があります。以下に例を示します。
 
<pre>/* translators: draft saved date format, see http://php.net/date */
 
<pre>/* translators: draft saved date format, see http://php.net/date */
 
$draft_saved_date_format = __('g:i:s a');</pre>
 
$draft_saved_date_format = __('g:i:s a');</pre>
By adding a <tt>translators:</tt> comment you can write a "personal" message to the translators, so that they know how to deal with the string.
+
<tt>translators:</tt> コメントを追加することで、翻訳者宛にメッセージを書くことができ、翻訳者が文字列がどんなものかを知ることができます。
  
=== Newline characters ===
+
=== 改行文字<!--Newline characters--> ===
  
Gettext doesn't like <tt>\r</tt> (ASCII code: 13) in translatable strings, so please avoid it and use <tt>\n</tt> instead.
+
Gettext は、翻訳する文字列に <tt>\r</tt> (ASCII code: 13) を好みません。 <tt>\r</tt> の代わりに <tt>\n</tt> を使用してください。
  
=== Handling JavaScript files ===
+
=== JavaScript ファイルを処理する<!--Handling JavaScript files--> ===
  
== Best Practices ==
+
== ベストプラクティス<!--Best Practices--> ==
  
Until we gather some WordPress-specific examples, use your time to read the short, but excellent article in the [http://www.gnu.org/software/gettext/manual/html_node/Preparing-Strings.html#Preparing-Strings gettext manual]. Summarized, it looks like this:
+
WordPress 特有の例を集める前に、[http://www.gnu.org/software/gettext/manual/html_node/Preparing-Strings.html#Preparing-Strings gettext manual] の短いけれど優れた記事を読みましょう。要約すると、以下のようになります。
* Decent English style &mdash; minimize slang and abbreviations.
+
* きちんとした英語 &mdash; スラングや省略は避けます。
* Entire sentences &mdash; in most languages word order is different than that in English.
+
* 文全体 &mdash; 多くの言語で、語順が英語と異なります。
* Split at paragraphs &mdash; merge related sentences, but do not include whole page of text in one string.
+
* 段落で分割 &mdash; 関連する文をまとめます。しかし、ページ全体を一つにしてはいけません。
* Use format strings instead of string concatenation &mdash; <tt>sprintf(__('Replace %s with %s'), $a, $b);</tt> is always better than <tt>__('Replace ').$a.__(' with ').$b; </tt>.
+
* 文字連結ではなく、文字列フォーマットを使用する &mdash; <tt>sprintf(__('Replace %s with %s'), $a, $b);</tt> <tt>__('Replace ').$a.__(' with ').$b; </tt> よりも常に好ましいです。
* Avoid unusual markup and unusual control characters &mdash; do not include tags that surround your text and do not leave URLs for translation, unless they could have version in another language.
+
* 不自然なマークアップや制御記号を避ける &mdash; テキストを囲むタグや、URL は翻訳に含めません(他の言語用のバージョンがある場合を除く)。
  
== I18n for theme and plugin developers ==
+
== テーマ開発者、プラグイン開発者のための国際化<!--I18n for theme and plugin developers--> ==
=== Choosing and loading a domain ===
+
=== ドメインの選択と読み込み<!--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.
+
テキストドメインは、WordPress が読み込む全翻訳から区別できるようにするための、一意識別子です。プラグインのベースネームを使用するのがいいでしょう。
  
Example: if your plugin is a single file called <tt>shareadraft.php</tt> or it is contained in a folder called <tt>shareadraft</tt> the best domain name you can choose is <tt>shareadraft</tt>. In case of a theme &mdash; choose the directory name.
+
: プラグインが、<tt>shareadraft.php</tt> という単一のファイル、あるいは <tt>shareadraft</tt> というフォルダ内にある場合、最適なドメイン名は <tt>shareadraft</tt> です。テーマの場合は、ディレクトリ名を用います。
  
The domain name is also used to form the name of the MO file with your plugins' translations. You can load them by invoking: 
+
ドメイン名は、プラグインの翻訳の MO ファイルの名前としても使用します。以下のようにして呼び出します。
load_plugin_textdomain( $domain, $path_from_abspath, $path_from_plugins_folder )
+
<code>load_plugin_textdomain( $domain, $path_from_abspath, $path_from_plugins_folder )</code>
  
as early as the <tt>init</tt> action.
+
<tt>init</tt> アクションの早い段階で呼び出されます。
  
Example:
+
:
  
$plugin_dir = basename(dirname(__FILE__));
+
<code> $plugin_dir = basename(dirname(__FILE__));
  load_plugin_textdomain( 'myplugin', 'wp-content/plugins/' . $plugin_dir, $plugin_dir );
+
  load_plugin_textdomain( 'myplugin', 'wp-content/plugins/' . $plugin_dir, $plugin_dir );</code>
  
This call tries to load <tt>myplugin.''locale''.mo</tt> 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|Installing WordPress in Your Language]].)
+
プラグインのベースディレクトリから <tt>myplugin-''locale''.mo</tt> を呼び出そうとします。''locale'' は、言語コードまたは国コード、あるいはその両方をアンダースコアでつないだもので、<tt>WPLANG</tt> で定義したものです。たとえばドイツ語のロケールは ''de'' ですし、デンマーク語のロケールは ''da_DK'' です。(言語コードと国コードについての詳細は、[[Installing_WordPress_in_Your_Language|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.
+
* 2.6 より前のバージョンでは、第二パラメータは、.mo ファイルを含むディレクトリの 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.)
+
* WordPress 2.6 以降では、第三パラメータは、.mo ファイルを含むディレクトリのプラグインディレクトリからの相対パスです。もし古いバージョンの WordPress の互換性が不要ならば、第二パラメータは空白でかまいません。)
  
For themes the process is surprisingly similar:
+
テーマの場合の処理も驚くほど似ています。
load_theme_textdomain(''domain-name'');
+
<code>load_theme_textdomain(''domain-name'');</code>
Put this call in your <tt>functions.php</tt> and it will search your theme directory for <tt>''locale''.mo</tt> and load it (where ''locale'' is the current language, i.e. ''pt_BR.mo'').
+
上記のコールを <tt>functions.php</tt> に記述すると、テーマディレクトリ内で<tt>''locale''.mo</tt> を探し、読み込みます (ここで ''locale'' は現在の言語、すなわち ''pt_BR.mo'' です)
  
==== I18n for widgets developed on 2.8+ ====
+
==== WordPress 2.8 以降のウィジェットの国際化<!--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 <tt>init</tt> 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.
+
WordPress 2.8 から新しいウィジェット API を使用しています。ウィジェット開発者は標準ウィジェットクラスとその関数を拡張すれば良いです。この新しい API では <tt>init</tt> 関数はありません。widget(), form(), update() 関数を使用してウィジェットをコーディングしたら、ウィジェットを登録する必要があります。テキストドメインは、ウィジェット登録後に読み込みされます。
  
Example:
+
:
// register FooWidget widget
+
<code> // register FooWidget widget
 
  add_action('widgets_init', create_function('', 'return register_widget("FooWidget");'));
 
  add_action('widgets_init', create_function('', 'return register_widget("FooWidget");'));
 
  $plugin_dir = basename(dirname(__FILE__));
 
  $plugin_dir = basename(dirname(__FILE__));
  load_plugin_textdomain( 'FooWidget', 'wp-content/plugins/' . $plugin_dir, $plugin_dir );
+
  load_plugin_textdomain( 'FooWidget', 'wp-content/plugins/' . $plugin_dir, $plugin_dir );</code>
This example registers a widget named ''FooWidget'', then sets the plugin directory variable and attempts to load the <tt>FooWidget-''locale''.po</tt> file.
+
この例は、''FooWidget'' という名前のウィジェットを登録し、プラグインディレクトリ変数を設定し、<tt>FooWidget-''locale''.po</tt> ファイル読み込みを試みます。
  
=== Marking strings in themes and plugins ===
+
=== テーマやプラグインで文字列をマークする<!--Marking strings in themes and plugins--> ===
  
All the rules from [[#Marking_Strings_for_Translation|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'''.
+
[[#Marking_Strings_for_Translation|上記で説明した]] ルールがすべて当てはまります。さらにもう一つ、ルールが加わります。そのルールは、'''ドメインをすべての __, _e, _c および __ngettext コールの引数に追加しなければならない'''、さもなければ、'''翻訳が動作しない'''
  
Examples:
+
:
  
 
* <tt>__('String')</tt> should become <tt>__('String', 'domain')</tt>
 
* <tt>__('String')</tt> should become <tt>__('String', 'domain')</tt>
142行目: 163行目:
 
* <tt>__ngettext('String', 'Strings', $c)</tt> should become <tt>__ngettext('String', 'Strings', $c, 'domain')</tt>
 
* <tt>__ngettext('String', 'Strings', $c)</tt> should become <tt>__ngettext('String', 'Strings', $c, 'domain')</tt>
  
Adding the domain by hand is a burden and that's why you can do it automatically:
+
ドメインを手作業で追加するのは大変ですね。自動化することができます。
  
* If your plugin is registered in the [http://wordpress.org/extend/plugins/ official repository], go to your '''Admin''' page there and scroll to '''Add Domain to Gettext Calls'''.
+
* プラグインが [http://wordpress.org/extend/plugins/ 公式リポジトリ] に登録されている場合、'''Admin''' ページへ行き、'''Add Domain to Gettext Calls''' に進みます。
Otherwise:
+
そうでない場合:
* Get the [http://svn.automattic.com/wordpress-i18n/tools/trunk/add-textdomain.php add-textdomain.php] script and execute it like this:
+
* [aadd-textdomain.php add-textdomain.php] スクリプトを入手し、以下を実行します。
 
  php add-textdomain.php -i ''domain'' ''phpfile'' ''phpfile'' ...
 
  php add-textdomain.php -i ''domain'' ''phpfile'' ''phpfile'' ...
After it's done, the domain will be added to all gettext calls in the files.
+
こうすると、ファイルにあるすべての gettext コールにドメインが追加されます。
 +
 
 +
=== POT ファイルの生成<!--Generating a POT file--> ===
 +
 
 +
[[#POT_Files|POT file]] を翻訳者に渡して翻訳してもらう必要があることを覚えていましたか?
 +
 
 +
POT ファイルを生成する方法はいくつかあります。
 +
#  [http://wordpress.org/extend/plugins/ 公式リポジトリ] に登録されている場合、'''Admin''' ページへ行き、'''Generate POT file''' に進みます。
 +
# リポジトリに登録されていない場合、SVN (SVN については [[Using Subversion]]/[[:en:Using Subversion]] を参照) から [http://i18n.svn.wordpress.org/tools/trunk/ i18n tools] ディレクトリをチェックアウトし、<tt>makepot.php</tt> スクリプトを以下のように実行します。
 +
<code> php makepot.php wp-plugin ''your-plugin-directory''</code>
 +
 
 +
このコマンドを実行するには、 gettext (GNU 国際化ユーティリティ) パッケージがサーバーにインストールされていることが必要です。
 +
完了したら、現在のディレクトリに POT ファイルがあるはずです。
 +
 
 +
プラグインと一緒に POT ファイルを提供するのは良い考えです。翻訳者がわざわざあなたに尋ねる必要がなくなります。
 +
 
 +
プラグインヘッダに以下のように追加すると、管理画面でプラグインを表示するときに WordPress がプラグインメタデータを国際化します。
 +
 
 +
Text Domain: your-text-domain
 +
Domain Path: /languages/
 +
 
 +
PO/MO ファイルに、ここに記入した英語に対応する翻訳を含めるのを忘れないようにしてください。
 +
 
 +
==== Gruntを使う ====
 +
 
 +
テーマやプラグインでグラントを使用する場合、<tt>.pot</tt>ファイルを生成するために、スティーブン·ハリスによる[https://github.com/stephenharris/grunt-pot grunt-pot] プラグインを使用することができます。
 +
プロジェクトに統合する手順については、彼のサイトを参照してください。 [http://stephenharris.info/grunt-wordpress-development-iii-tasks-for-internationalisation/ his site]
 +
 
 +
==== content例 ====
 +
 
 +
各翻訳可能な文字列は次のようにフォーマットされます。:
 +
 
 +
<pre>#: comments.php:28
 +
msgid "Comments:"
 +
msgstr ""</pre>
 +
 
 +
=== PO ファイル ===
 +
Every translator takes the WordPress <tt>.pot</tt> file and translates the <tt>msgstr</tt> sections to their own language. The result is a <tt>.po</tt> file with the same format as a <tt>.pot</tt>, but with translations and some specific headers.
  
=== Generating a POT file ===
+
=== MO ファイル ===
 +
From a resulting <tt>.po</tt> translation file a <tt>.mo</tt> file is compiled. This is a binary file which contains all the original strings and their translations in a format suitable for fast translation extraction. The conversion is done using the <tt>msgfmt</tt> tool:
  
You remember the [[#POT_Files|POT file]] is the one you need to hand to translators, so that they can do their work, don't you?
+
msgfmt -o &lt;output&gt;.mo &lt;input&gt;.po
  
Once that is in place, there are a couple of ways to generate a POT file for your plugin:
+
If you have a lot of <tt>.po</tt> files to convert at once, you can run it as a batch. For example, using a <tt>bash</tt> command:
# If your plugin is registered in the [http://wordpress.org/extend/plugins/ official repository], go to your '''Admin''' page there and scroll to '''Generate POT file'''.
+
<pre>
# If your plugin is not in the repository, you can checkout the [http://svn.automattic.com/wordpress-i18n/tools/trunk/ wordpress-i18n tools] directory from SVN (see [[Using Subversion]] to learn about SVN) and then run the <tt>makepot.php</tt> script like this:
+
# Find PO files, process each with msgfmt and rename the result to MO
php makepot.php wp-plugin ''your-plugin-directory''
+
for file in `find . -name "*.po"` ; do msgfmt -o ${file/.po/.mo} $file ; done
 +
</pre>
  
You need the gettext (GNU Internationalization utilities) package to be installed in your server before you can run the above command
+
==関連資料<!--Resources-->==
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.
+
* [http://zone.maple4ever.net/blog/archives/366/ WordPress プラグイン日本語化 Tips]
 +
* [http://dogmap.jp/2011/07/01/wordpress-plugin-description-translation/ WordPress Plugin 作者に覚えておいて欲しいこと](dogmap.jp)- プラグインヘッダ内のテキストの国際化について。
  
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:
+
===英語===
<code>
+
* [http://ottopress.com/2013/language-packs-101-prepwork/ Language Packs 101 – Prepwork]
Text Domain: your-text-domain
+
* [http://clivern.com/how-to-internationalize-your-wordpress-plugin/ How to internationalize your wordpress plugin]
</code>
+
* [http://www.geertdedeckere.be/article/loading-wordpress-language-files-the-right-way Loading WordPress language files the right way] - but careful re custom suggestion - see 101 above
 +
* [http://markjaquith.wordpress.com/2011/10/06/translating-wordpress-plugins-and-themes-dont-get-clever/ Translating WordPress Plugins and Themes: Don’t Get Clever]
 +
* [http://wp.smashingmagazine.com/2011/12/29/internationalizing-localizing-wordpress-theme/ Internationalizing And Localizing Your WordPress Theme]
 +
* [http://ottopress.com/2012/internationalization-youre-probably-doing-it-wrong/ Internationalization: You’re probably doing it wrong]
 +
* [http://ottopress.com/2012/more-internationalization-fun/ More Internationalization Fun]
  
==Resources==
+
{{原文|I18n_for_WordPress_Developers|85182}} <!-- 04:17, 2 April 2010 Lag47 -->
[http://urbangiraffe.com/articles/localizing-wordpress-themes-and-plugins/ Localizing WordPress Themes and Plugins]
+
  
{{原文|I18n_for_WordPress_Developers|81544}} <!-- 16:27, 31 December 2009  Dimadin -->
+
{{NeedTrans|一部}}
  
 
{{DEFAULTSORT:I18n_for_WordPress_Developers}}
 
{{DEFAULTSORT:I18n_for_WordPress_Developers}}

2015年6月21日 (日) 18:36時点における最新版

plugin internationalization documentation はこちらにあります(英語) Plugin Developer Handbook

plugin localization documentation はこちらにあります(英語)Plugin Developer Handbook

theme internationalization documentation はこちらにあります(英語)Theme Developer Handbook

theme localization documentation はこちらにあります(英語)Theme Developer Handbook


国際化とは

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 ツールを使用して変換します。

典型的な msgfmt コマンドは、msgfmt -o filename.mo filename.po です。

fたくさんの PO ファイルを一度に変換するために、バッチ処理を実行することができます。例えば、以下のように bash コマンドを使用します。

# PO ファイルを探し、それぞれに msgfmt を実行し、出力を MO にリネームする
for file in `find . -name "*.po"` ; do msgfmt -o `echo $file | sed s/\.po/\.mo/` $file ; done

テキストドメイン

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."), $city, $zipcode);

ここでは都市名の後に郵便番号が表示されています。しかし、最初に郵便番号、次に都市の順のほうが適切な言語もあるでしょう。上の例のように %s 接頭辞を使用することで、対処可能になります。翻訳は、以下のようにすることができます。

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

(訳注: 実際には printf の中身ではなく .po ファイルで順序を変える --Mizuno 2010年4月12日 (月) 05:30 (UTC))

複数

スパムの例 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 ファイルを処理する

ベストプラクティス

WordPress 特有の例を集める前に、gettext manual の短いけれど優れた記事を読みましょう。要約すると、以下のようになります。

  • きちんとした英語 — スラングや省略は避けます。
  • 文全体 — 多くの言語で、語順が英語と異なります。
  • 段落で分割 — 関連する文をまとめます。しかし、ページ全体を一つにしてはいけません。
  • 文字連結ではなく、文字列フォーマットを使用する — sprintf(__('Replace %s with %s'), $a, $b);__('Replace ').$a.__(' with ').$b; よりも常に好ましいです。
  • 不自然なマークアップや制御記号を避ける — テキストを囲むタグや、URL は翻訳に含めません(他の言語用のバージョンがある場合を除く)。

テーマ開発者、プラグイン開発者のための国際化

ドメインの選択と読み込み

テキストドメインは、WordPress が読み込む全翻訳から区別できるようにするための、一意識別子です。プラグインのベースネームを使用するのがいいでしょう。

例: プラグインが、shareadraft.php という単一のファイル、あるいは shareadraft というフォルダ内にある場合、最適なドメイン名は shareadraft です。テーマの場合は、ディレクトリ名を用います。

ドメイン名は、プラグインの翻訳の MO ファイルの名前としても使用します。以下のようにして呼び出します。 load_plugin_textdomain( $domain, $path_from_abspath, $path_from_plugins_folder )

init アクションの早い段階で呼び出されます。

例:

$plugin_dir = basename(dirname(__FILE__));

load_plugin_textdomain( 'myplugin', 'wp-content/plugins/' . $plugin_dir, $plugin_dir );

プラグインのベースディレクトリから myplugin-locale.mo を呼び出そうとします。locale は、言語コードまたは国コード、あるいはその両方をアンダースコアでつないだもので、WPLANG で定義したものです。たとえばドイツ語のロケールは de ですし、デンマーク語のロケールは da_DK です。(言語コードと国コードについての詳細は、Installing WordPress in Your Language を参照してください。)

  • 2.6 より前のバージョンでは、第二パラメータは、.mo ファイルを含むディレクトリの ABSPATH からの相対パスとし、第三パラメータは空白にする必要があります。
  • WordPress 2.6 以降では、第三パラメータは、.mo ファイルを含むディレクトリのプラグインディレクトリからの相対パスです。もし古いバージョンの WordPress の互換性が不要ならば、第二パラメータは空白でかまいません。)

テーマの場合の処理も驚くほど似ています。 load_theme_textdomain(domain-name); 上記のコールを functions.php に記述すると、テーマディレクトリ内でlocale.mo を探し、読み込みます (ここで locale は現在の言語、すなわち pt_BR.mo です)。

WordPress 2.8 以降のウィジェットの国際化

WordPress 2.8 から新しいウィジェット API を使用しています。ウィジェット開発者は標準ウィジェットクラスとその関数を拡張すれば良いです。この新しい API では init 関数はありません。widget(), form(), update() 関数を使用してウィジェットをコーディングしたら、ウィジェットを登録する必要があります。テキストドメインは、ウィジェット登録後に読み込みされます。

例: // 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 );

この例は、FooWidget という名前のウィジェットを登録し、プラグインディレクトリ変数を設定し、FooWidget-locale.po ファイル読み込みを試みます。

テーマやプラグインで文字列をマークする

上記で説明した ルールがすべて当てはまります。さらにもう一つ、ルールが加わります。そのルールは、ドメインをすべての __, _e, _c および __ngettext コールの引数に追加しなければならない、さもなければ、翻訳が動作しない

例:

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

ドメインを手作業で追加するのは大変ですね。自動化することができます。

  • プラグインが 公式リポジトリ に登録されている場合、Admin ページへ行き、Add Domain to Gettext Calls に進みます。

そうでない場合:

  • [aadd-textdomain.php add-textdomain.php] スクリプトを入手し、以下を実行します。
php add-textdomain.php -i domain phpfile phpfile ...

こうすると、ファイルにあるすべての gettext コールにドメインが追加されます。

POT ファイルの生成

POT file を翻訳者に渡して翻訳してもらう必要があることを覚えていましたか?

POT ファイルを生成する方法はいくつかあります。

  1. 公式リポジトリ に登録されている場合、Admin ページへ行き、Generate POT file に進みます。
  2. リポジトリに登録されていない場合、SVN (SVN については Using Subversion/en:Using Subversion を参照) から i18n tools ディレクトリをチェックアウトし、makepot.php スクリプトを以下のように実行します。

php makepot.php wp-plugin your-plugin-directory

このコマンドを実行するには、 gettext (GNU 国際化ユーティリティ) パッケージがサーバーにインストールされていることが必要です。 完了したら、現在のディレクトリに POT ファイルがあるはずです。

プラグインと一緒に POT ファイルを提供するのは良い考えです。翻訳者がわざわざあなたに尋ねる必要がなくなります。

プラグインヘッダに以下のように追加すると、管理画面でプラグインを表示するときに WordPress がプラグインメタデータを国際化します。

Text Domain: your-text-domain
Domain Path: /languages/

PO/MO ファイルに、ここに記入した英語に対応する翻訳を含めるのを忘れないようにしてください。

Gruntを使う

テーマやプラグインでグラントを使用する場合、.potファイルを生成するために、スティーブン·ハリスによるgrunt-pot プラグインを使用することができます。 プロジェクトに統合する手順については、彼のサイトを参照してください。 his site

content例

各翻訳可能な文字列は次のようにフォーマットされます。:

#: comments.php:28
msgid "Comments:"
msgstr ""

PO ファイル

Every translator takes the WordPress .pot file and translates the msgstr sections to their own language. The result is a .po file with the same format as a .pot, but with translations and some specific headers.

MO ファイル

From a resulting .po translation file a .mo file is compiled. This is a binary file which contains all the original strings and their translations in a format suitable for fast translation extraction. The conversion is done using the msgfmt tool:

msgfmt -o <output>.mo <input>.po

If you have a lot of .po files to convert at once, you can run it as a batch. For example, using a bash command:

# Find PO files, process each with msgfmt and rename the result to MO
for file in `find . -name "*.po"` ; do msgfmt -o ${file/.po/.mo} $file ; done

関連資料

日本語

英語

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

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