web-dev-qa-db-ja.com

Yii:多言​​語のウェブサイト-ベストプラクティス

Yii素晴らしいフレームワークであり、yiic Shellで作成されたサンプルWebサイトは、開始するのに良いポイントです...しかし、残念ながら、多言語Webサイトのトピックはカバーしていません。ドキュメントショートメッセージの翻訳のトピックをカバーしていますが、多言語コンテンツを維持していません...

少なくとも2つの言語である必要があるウェブサイトで作業を開始しようとしていますが、そのためのコンテンツを保持するための最良の方法は何でしょうか...問題は、コンテンツが一般的な要素と広範囲に混在していることです(埋め込まれたビデオファイルのように)。

私はそれらのコモンズを複製することを避ける必要があります...これまで私はテキストを含む配列の配列(通常は1〜2個の短い段落以下)を持っていましたが、ビューファイルは配列からテキストをレンダリングするだけでした。

ここで、配列に保持することは避けたいと思います(二重引用符 ""を付ける場合は注意が必要であり、一般的に不便です...)。

それで、それらの短い段落を維持するための最良の方法は何ですか?それらを(id | msg_id | language | content)のようにDBに保持してから、msg_idと言語で選択する必要がありますか?それでも、いくつかのmsg_idを作成し、それらをビューファイルに埋め込む必要があります...

Yiiにいくつかの解決策がある推奨パラダイムはありますか?

ありがとう、m。

23
migajek

Yiiアプリケーションはデフォルトでyii :: t()メソッドを使用してテキストメッセージを翻訳します。メッセージソースには3つの異なるタイプがあります。

  1. CPhpMessageSource :翻訳はキーと値のペアとしてPHP配列に格納されます。
  2. CGettextMessageSource :翻訳はGNU Gettextファイル。(POファイル)として保存されます。
  3. CDbMessageSource :メッセージの翻訳はデータベーステーブルに保存されます。

私が誤解しない限り、あなたは翻訳に古典的な配列を使用しています。翻訳操作には、GetTextファイルとPOファイルをYiiで使用することをお勧めします。

翻訳とi18nに関する多くの情報をyiiこの 公式ドキュメントページ で見つけることができます。

17
edigu

Gettextは翻訳のしやすさには優れていますが、デフォルトのPHP実装はスレッドセーフではありません。Yiiしたがって、独自のアンパッカーを使用するため、処理時間が大幅に増加します。 php配列。

大量のトランザクションサイトをセットアップしていたため、パフォーマンスへの影響は許容できませんでした。また、APCを使用することで、PHP変換をキャッシュして、パフォーマンスをさらに向上させることができます。

したがって、私のアプローチはPHP配列を使用することでしたが、翻訳を容易にするために翻訳をDBに保持し、翻訳が変更されたときに必要なファイルを生成しました。

DBはこれに似ています:

TABLE Message            // stores source language, updated by script
 id INT UNSIGNED
 category VARCHAR(20)         // first argument to Yii::t()
 key TEXT                     // second argument to Yii::t()
 occurences TINYINT UNSIGNED  // number of times found in sources

TABLE MessageTranslation // stores target language, translated by human  
 id INT UNSIGNED
 language VARCHAR(3)          // ISO 639-1 or 639-3, as used by Yii
 messageId INT UNSIGNED       // foreign key on Message table
 value TEXT
 version VARCHAR(15)
 creationTime TIMESTAMP DEFAULT NOW()
 lastModifiedTime TIMESTAMP DEFAULT NULL
 lastModifiedUserId INT UNSIGNED

次に、CLIツールのyiic'message 'コマンドを変更して、収集した文字列をDBにダンプしました。

http://www.yiiframework.com/wiki/41/how-to-extend-yiic-Shell-commands/

DBに入ると、簡単なCMSをセットアップして、翻訳者に簡単な翻訳方法を提供すると同時に、バージョン情報の提供、古いバージョンへの復帰、翻訳者の品質のチェックなどを行うことができます...

同じくyiicから変更された別のスクリプトは、DB情報を取得し、それをPHP配列にコンパイルします。基本的に各言語の2つのテーブルを結合し、「メッセージ」を使用して配列を構築します。 key 'および' MessageTranslation '。' value'as(他に何がありますか?)key => value ...言語で指定されたフォルダーの 'Message'。 'category'から名前が付けられたファイルに保存します。

生成されたファイルは、通常どおりYii CPhpMessageSourceによってロードされます。

画像の場合、これは適切な言語のフォルダーに画像を配置し、リンク時にアプリの言語を取得するのと同じくらい簡単でした。

<img src="/images/<?php echo Yii::app()->language; ?>/help_button.png">

実生活では、言語文字列から国を取り除くための小さなヘルパーメソッドを作成したことに注意してください。「en_us」は「en」である必要があります。

19
ianaré

ここで関係しているのは、ページ上の静的なテキスト/メッセージをどのように翻訳するかであり、YiiはYii:t()を使用してそれをかなりうまく解決し、Ediguの答えはそれに対するものだと思います。

データベース内の動的コンテンツの翻訳に関するFlexicaCMSの投稿をチェックします。最終的には、静的テキスト/メッセージの問題を解決した後の次の投稿になります。これは、Yiiの動作を使用した本当に良いアプローチです。 FlexicaCMSの作成者が、コンテンツの翻訳を心配のないものにするため、そのように翻訳をサポートすることに意欲的すぎるかどうかはわかりません。本当に素晴らしいことです。

彼らが言及していないことの1つは、翻訳されたページのURLです。たとえば、your.site.com/fr /translated_article_title.htmlです。つまり、SEOに役立つように、URLには/ language_id /の部分が含まれている必要があります。

1
user366852

Yii1とYii2では、yii\i18n\GettextMessageSourceはPOまたはMOファイルのロードを強化するためにYii完璧なキャッシュエンジン(ソースを見てください)を使用しません。これらのファイルをロードすることはお勧めしません。 phpの純粋なコード(yii\i18n\GettextMessageSourceを含む)を使用する(php array idxよりも遅い): http://mel.melaxis.com/devblog/2006/04/10/benchmarking-php-localization -is-gettext-fast-enough /

ただし、MOファイルのphp gettext extは、キャッシュを使用するため、変換php配列よりも数高速ですが、欠点は、MOを変更するたびにサーバーを再起動する必要があることです。

最善の解決策は、独自のコードライブラリでyii\i18n\GettextMessageSourceを拡張し、GettextMessageSourceにキャッシュ機能を追加してパフォーマンスを向上させ、拡張バージョンをコンポーネントとして使用することだと思います。

protected function loadMessages($category, $language);

キャッシュと比較するためにすべてのロードでMOの変更日をチェックするのではなく、MOまたはPOファイルが変更されたときにキャッシュをクリアします(スケジュールの場合もあります)。

0
Alix