PUFF-J
PUFF-Jは、ローカライズされるリソースを記述するための、UTF-8文字エンコードを使用するJSONベースのファイル形式です。リソースとは、翻訳のためにリンギストに提出される文字列です。 この形式では、リソースをマップの形式で提供できます。- キー:リソースの一意の識別子。
- 値:リソース値を含むオブジェクト。リソース値は、翻訳のためにリンギストに提出される値です。
- リソースの説明。リソースが使用されるコンテキストなどを含めることができます。
- リソースのライフサイクル(翻訳プロセス中またはリソースが使用される実行時)において、そのリソースがどのように処理されるかに関する追加情報。
リソースレベルのプロパティ
リソース識別子
翻訳用に提出される各リソースは、一意の識別子によって識別されます。このリソースIDは、リソースオブジェクトのプロパティ名として指定します。JSONではこの文字列に実質的に任意のUnicode文字を使用できますが、PUFF-Jでは次の文字セットに制限されています。\wは[a-zA-Z_0-9]と同じです。
リソース値
リソース値は、翻訳のためにリンギストに提出される実際の値です。通常はvalueプロパティに指定され、次の3つのタイプのいずれかにすることができます。
オプションのプロパティ
リソースオブジェクトには、追加のプロパティを含めることができます。これらのプロパティを通じて、翻訳プロセスでのリソースの処理方法に関する詳細情報を提供します。translate- 文字列を翻訳するかどうかを示すフラグ。省略されている場合、または値がtrueの場合、文字列を翻訳する必要があります。これは、翻訳リクエストに含められることを意味します。
note- コンテキストに関するノート。追加することを強く推奨します。
- 各ノートの文字数は3,000文字に制限されます。
- ノートは開発者のコメントを表し、文字列やプレースホルダーに関して、翻訳者の助けとなる幅広いコンテキストを提供します。
リソースタイプ
前述のとおり、翻訳のためにリンギストに送信されるリソース値は、次の3つのタイプのいずれかにすることができます。 このセクションでは、各タイプの詳細と、それらをPUFF-Jファイルで適切に表現する方法に関するベストプラクティスを説明します。重要なポイント
-
MessageFormatの複雑な複数形パターンや選択パターンを編集したり読み取ったりする労力を軽減するには、構造化リソース値タイプを使用します。 -
ICUの
MessageFormatのドキュメント(英語のみ)より: 複雑な引数(複数形分岐など)を持つメッセージ文字列では、最小限の部分だけを処理したくなりがちです。しかし、これは翻訳者にとって2つの理由から困難です。第一に翻訳者には、引数のサブメッセージに含まれている文の断片が、文の残りの部分とどのように関係するかがわからない場合があります。第二に、メッセージ全体を翻訳対象言語に合わせようとしても、引数の文の一部を短縮または拡張してよいかどうか、どのように短縮または拡張すればよいかを翻訳者が知る方法はありません。 推奨される方法:可能であれば、複雑な引数をメッセージの最も外側の構造として使用し、そのサブメッセージ内に文全体を記述します。選択分岐と複数形分岐の引数を入れ子にする場合は、選択分岐引数(およびその固定の選択肢のセット)を外側に配置し、複数形分岐引数(なるべく最大1つ)を内側に入れ子にします。 - コンテキストノートを追加します。これらのノートは開発者のコメントを表し、文字列やプレースホルダーに関する幅広いコンテキストを翻訳者に提供します。また、複数に解釈される可能性のある単語や概念を、翻訳者が理解するために役立つ情報も提供します(たとえば、「window」という単語は、コンピューター上のウィンドウを意味する場合と、家の窓を意味する場合があります)。
文字列タイプ
単純な文字列はJSON文字列として表されます。文字列はMessageFormatパターンとして記述され、必要に応じてパラメーター(文字列、数値、日付、時刻など)のプレースホルダーを含めることができます。パラメーターは実行時にフォーマットされ、挿入されます。
文字列には、エスケープされた制御文字を除く任意のUnicode文字を使用できます。エスケープ構文を参照してください。
ただし、ストレートアポストロフィU+0027(')(英語(米国)キーボードのデフォルトの一重引用符)は例外です。これはJSONでは有効ですが、MessageFormatのパターンでは特殊文字として扱われます。この文字はソース文字列で使用しないことをお勧めします。一重引用符を表すには、代わりに右一重引用符U+2019(’)文字を使用してください。
ソース文字列に一重引用符が含まれていなくても、翻訳された文字列に一重引用符を含めることが必要になる場合があります。これは、たとえばフランス語の翻訳で特によく起こります。この場合は、右一重引用符U+2019(’)文字を使用するように翻訳者に指示してください。開発者がコンテキストノートで翻訳者に注意を促すのも有効な方法です。
MessageFormatパターンにリテラルのストレートアポストロフィ文字をあえて含める必要がある場合は、ストレートアポストロフィを2つ続けることでエスケープできます。たとえば、MessageFormatパターン内の''は「‘」としてレンダリングされます。
もう1つの例外は中かっこです。これもMessageFormatパターンの特殊文字です。ストレートアポストロフィを使用する必要のあるケースの1つが、MessageFormatパターンにリテラルの中かっこ文字を含めるためのエスケープ文字として使用する場合です。たとえば、MessageFormatパターン内の'{''}'は「{’}」としてレンダリングされます。このような用法については、翻訳者向けのコンテキストノートを含めるのが最適です。また、構文が直観的でないため、返された翻訳を注意深く確認することも必要です。
プレースホルダーがある場合とない場合の単純な文字列の例(簡略な表現):
構造化リソース値タイプ
構造化リソース値タイプを使用すると、MessageFormatの複雑な複数形パターンや選択パターンを編集したり読み取ったりする労力が軽減されます。パラメーターに基づいて分岐するサブパターンを、パラメーター値をキーとするマップとして提供できます。マップ内の各項目は、サブパターンのさまざまな分岐を表します。
複数形分岐タイプ
推奨される方法:MessageFormatの複雑な複数形パターンを記述する作業は込み入っていて、間違いを引き起こすことがよくあります。この理由から、そしてリソースの読みやすさを向上させるためにも、開発者には、複数形分岐構造化リソース値タイプを使用して複数形分岐形式を構築することを強くお勧めします。この形式により、複数形分岐の項目ごとに翻訳可能な文全体を記述することが促され、複雑なMessageFormat構造を回避できます。この方法に従うと、高品質な翻訳を実現するために役立ちます。
文字列に数値を挿入するときによく問題となるのが、最終的に文法的に正しい文を作成することです。たとえば、次のようなMessageFormatパターンがあるとします。
MessageFormatには複数形を処理するためのパターン構文がありますが、扱いやすくはありません。そこで、代わりに複数形分岐構造化リソース値タイプの構文を使用すると、どの言語でも文法的に正しい複数形を記述することが簡単になります。
複数形分岐リソースを構築するには、次の2つのパラメーターを指定する必要があります。
param:メッセージを選択するために使用する変数の名前。pluralItems:ルールが関連付けられた文字列のリスト。これらの項目から選択されます。
paramプロパティで指定します。MessageFormat内のパラメーターは名前でも番号でも指定できるため、このプロパティは文字列と数値のどちらでも構いません。
複数形バリアントはpluralItemsプロパティに格納します。このプロパティは、複数形分岐パラメーターの値と複数形バリアントのマップです。
パラメーター名には次の形式を使用できます。
[:Pattern_Syntax:]と[:Pattern_White_Space:]はICU UnicodeSet(英語のみ)です。
パラメーター名にスペースを含めることはできません。
使用できる複数形分岐パラメーターの値は次のとおりです。
zeroonetwofewmany^(=[0-9]+)$other(必須:otherは常に指定する必要があります。これは、パラメーター値がほかのどのルールにも一致しない場合にトリガーされるルールです)
=0、one、otherが使用されます。文法上、two、few、many、^(=[0-9]+)$に対応する明確なユースケースはありません。ソース文字列が英語の場合、後者の値がソースの複数形分岐構造化リソース値に現れることはありません。
ルールは、列挙ルールと数値ルールの2つのカテゴリーに分けられます。列挙ルールには、zero、one、two、few、many、otherがあります。名前は示唆的ですが、これらのルールが必ずしも「文字どおり」の意味になるとは限りません。ルールがトリガーされるロジックはロケールごとに異なります。たとえば英語では、oneルールは値が1の場合にトリガーされます。しかしこのルールは、日本語や中国語など、文法上複数形のない言語ではトリガーされず、ほかのいくつかのロケールでは、1で終わる数値(21、31など)のような異なる値に対してトリガーされます。
数値ルールは特定の値に一致します。後述の例では、=0ルールが値0に一致します。数値ルールは列挙ルールよりも優先されます。特定のメッセージを値に結び付けるには、数値ルールを記述する必要があります。たとえば、「あと1回でアカウントがロックされます」というメッセージを表示する場合は、oneルールではなく=1ルールを使用して、パラメーター値が1の場合にのみ常にメッセージが表示されるようにします。
リソースを英語で作成するときは、例で使用されている=0、one、otherのルールを常に記述してください。ローカリゼーションでは、翻訳プロセス中にほかのロケールで必要となるすべてのルールを生成する必要があります。必要に応じて、上記の=1の場合のような数値ルールを追加します。
複数形分岐構造化リソース値の例を以下に示します。
複数形分岐の使用が適した場面
文に数値や価格を挿入する場合は、常に複数形分岐を使用します。以下に例を示します。複数形分岐の使用が適さない場面
数値や値が文の一部でない場合は、複数形分岐を使用しません。以下に例を示します。複数形分岐タイプのサンプルユースケース
サンプルのユースケースを見てみましょう。ここでは、顧客のカートに入っている商品の数を表示するために、文字列に数値を挿入する必要があるとします。以下に例を示します。MessageFormatパターンを編集したり読み取ったりする手間もなくなります。
推奨: 以下の形式を強くお勧めします。複数形分岐構造化リソース値タイプでは、複数形分岐項目ごとに翻訳可能な文全体を記述します。これにより、翻訳者にとっての読みやすさが向上し、文字列の詳細なコンテキストが与えられます。また、文全体を提供すれば、言語の自然な流れに合わせて翻訳の語順を並べ替えることが容易になります。次の例には、翻訳者に追加情報を提供するコンテキストノートも含まれています。
選択分岐タイプ
文字列に名前や名詞を挿入すると、その文法上の性別プロパティが、文字列内で関連するほかの単語に影響する可能性があります。MessageFormatの選択パターンは、文法上の性別に基づく語尾変化の処理を支援するように設計されています。詳細については、ICUのSelectFormatのドキュメント(英語のみ)を参照してください。
選択分岐構造化リソース値タイプは、MessageFormatの選択パターンの使用方法を簡素化するものです。このタイプは、任意の値を持つパラメーターに基づく分岐を表します。選択分岐構造化リソース値には、次の2つの必須プロパティがあります。
param:メッセージを選択するために使用する変数の名前。selectItems:パラメーター値が関連付けられた文字列のリスト。これらの項目から選択されます。
paramプロパティで指定します。MessageFormatパターン内のパラメーターは名前でも番号でも指定できるため、このプロパティは文字列と数値のどちらでも構いません。
分岐はselectItemsプロパティ内の項目として指定します。選択分岐項目のキーには、JSONの文字列型に適用される制限以外の制限はありません。
パラメーター名には次の形式を使用できます。
[:Pattern_Syntax:]と[:Pattern_White_Space:]はICU UnicodeSet(英語のみ)です。
パラメーター名にスペースを含めることはできません。
selectItemsのリスト内には、otherルールを含める必要があります。otherは、パラメーター値がほかのどの項目キーにも一致しない場合にトリガーされるルールです。
選択分岐構造化リソース値の例
選択分岐タイプのサンプルユースケース
サンプルのユースケースを見てみましょう。ここでは、ホストの性別に応じて、次の文字列のいずれかを表示する必要があるとします。selectItemsには、項目の1つとしてotherルールを指定する必要があることに注意してください。
入れ子
文は、2つ以上の複数形分岐パラメーターや選択分岐パラメーターに応じて変化する場合があります。{hostName}は、分岐項目の選択とは関係のないほかのパラメーターを複数形分岐や選択分岐に含めることができる例として追加されています。
エスケープ構文
PUFF-Jの文字列は、標準のJSONの定義(英語のみ)に従います。 文字列は、0文字以上の連続するUnicode文字を二重引用符で囲んだものです。エスケープにはバックスラッシュが使用されます。文字は単一文字の文字列として表されます。文字列はCやJavaの文字列とよく似ています。複数行の文字列
JSONの定義では、複数行の文字列はサポートされていません。改行文字はすべて\nに置き換える必要があります。

