web-dev-qa-db-ja.com

テンプレートの文字列を、表示されるすべてのページで翻訳可能にする方法は?

* .tpl.phpファイルで t() を呼び出しています。例として、製品とproduct.tpl.phpファイルについて話しているとしましょう。

テンプレート内の文字列は、実際に使用されるまで認識されません。それについて Drupal.orgのスレッド があり、それが正確であることがわかりました。悲しいことに、たとえば http://example.com/pl/product/2 に行くと、その文字列はlocationフィールドが{locales_source}に設定された/pl/product/200テーブルに保存されます。

ユーザーが Localization client モジュールのオンサイト翻訳ツールを使用して翻訳できるようにして、適切なコンテキストで実際に翻訳内容を確認できるようにします。ソースの場所が/pl/product/200に設定されている場合、ID 200の製品は、文字列が翻訳されることが示されている唯一の製品です。さらに悪いことに、その特定の製品でユーザーに翻訳を強制できる場合は、ロシア語にも翻訳できる必要があり、場所が/ru/product/PIDに設定されている製品はありません。

l10n_clientツールのすべての言語、すべての製品ですべての文字列を表示するために、データベース内の場所の文字列を再フォーマットする方法はありますか?

私はそれを次のように設定しようとしました:

  • ; sites/default/themes/mytheme/product.tpl.php
  • sites/default/themes/mytheme/product.tpl.php
  • sites/default/modules/mymodule/mymodule.module(テーマデータを生成するモジュール)

しかし、それだけでは翻訳ツールから見えなくなりました。

ローカリゼーションクライアント のバグではないと確信しています。この文字列は、この文字列が発生したと伝えられた場所に表示されます。 Drupal 7の翻訳システムも同様です。これはすでに議論および報告されており、何も変更されていません。これはバグレポートではないので、私たちが協力しなければならないものをどのように扱うか。


/ data module が操作するテキストとは何の関係もないテキストについて話しています。 製品を翻訳したくありません。製品イメージギャラリーテンプレートの[前へ-次へ]のように、製品自体とは関係のないテンプレート文字列だけです。

たとえば、モジュールは15のサムネイルを返しますが、一度に5つを表示するのはテーマの仕事です。また、前/次のリンクには、altおよびtitle属性が必要です。翻訳済み。しかし、私のモジュールはそれを知りません。そして、決してする必要はありません。

14
Mołot

あなたの要件:
私のサイトが複数の言語で機能するために
認証されたユーザーとして
t()関数で実行された、サイトのコードベースにあるすべての翻訳呼び出しを一度に翻訳できるようにする必要があります。

その要件の説明は、あなたが求めているものに近いですか?


クローラー

誰かが言ったように-クローラーはサイト全体を理論的に通り抜けて、すべてのt()呼び出しの登録を強制することができます。しかし1)クローラークロールするページがわかりません。 2)したがって、クロールするページのリストを維持することは考えていません。 3)クローラー、ピリオドを使用したくない。えww。ただ、ww正しい?


問題

  1. すべての翻訳文字列のリストはありません。
  2. Drupal/PHPは、コンパイルされるCとは異なり、動的言語です。たとえば、このコードベース全体をコンパイルしてから、この関数のすべてのインスタンスt()を見つけ、それらのインスタンスをデータベースに登録し、t()のすべての登録済みインスタンスを翻訳します。一度に。私たちは私たちのテーブルにあるオプションではないと思います。
  3. 静的コード分析ツールは、クローラーが役に立たないのと同じ理由で役に立たないでしょう。このt()がこのファイルで見つかりました。すごい!どのURLで使用されていますか?コンテキストは何ですか?

現在のツール(Drupalおよびいくつかのcontribモジュール)と現在の制約(リアルタイムのテーマ呼び出し->テンプレートファイル-> t()呼び出しに依存)で問題を攻撃すると、出口がないように見えますここの路地。箱から出して少し考える必要があるかもしれません。


必要なもの

  1. 現在使用している翻訳文字列とそのコンテキストは何かを教えてくれるデータソース、モデルが必要です-
  2. プロアクティブなデータモデル。現在のデータモデルはリアクティブです(t()への呼び出しが発生するたびにモデルが更新されます)。プロアクティブなデータモデルが必要です。実際に顧客が実行する前に、アプリケーションがt()インスタンスを探す処理を行うモデルです。
  3. コンテキストが必要です。 t()だけではうまくいきません。なぜなら、「foo」を翻訳していることはわかりませんが、翻訳先のターゲット言語は、t()が発生している場所のURLに依存しているためです。たとえばラッパー呼び出しを使用してt()呼び出しにターゲット言語をハードコード化できたとしても、それはあなたの目的には機能しません。

私は、もしそれらがあったとしても、私たちの問題を助けるであろういくつかのツールを特定しました。これらのツールを使用して、データモデルにアクセスし、次のように言うことができます。t()でラップされ、まだ入力されていないすべての文字列を教えてください。次に、これらの翻訳を挿入します。ありがとうございました。

そして次に顧客が来たときに、翻訳が整っています。

どのように...これらのツールを構築しますか?


制約

  1. ターゲット言語をテンプレートに含めることはできません。これは、URLによって決定されます。文字列が任意の言語をサポートする必要があると仮定します。
  2. 翻訳された文字列をテンプレートに含めることはできません。翻訳はデータベースに保存されます。

私は問題をより深く考え、いくつかの課題と制約を特定したので、そこで利用可能なソリューションを検討するか、カスタムソリューションを作成することを考えることができます。

ソリューションブレインストーミング

「すべて」を結びつけるものが必要です。エンティティはどうですか?

  • エンティティは、翻訳が必要な製品を保持できます。
  • エンティティは、翻訳が必要な製品とそのコンテキストの間の関係(接着剤)を提供できます。
  • エンティティは、たとえば、フィールドに製品のデフォルトのURLロケーションを指定できます。
  • トークンは、製品が表示される別の場所(言語?)を指定するために使用できます。
  • エンティティは、必要なプロアクティブなデータモデルとそのコンテキストを提供します。これにより、データベースにアクセスしてすべての製品エンティティを取得し、フィールドX、Y、およびZの翻訳文字列がない場合は、それらの翻訳文字列を作成できます。

次に顧客が/pl/product/200を取得したら、dbにアクセスして製品200を検索し、既存のpl変換を取得します。その製品のタイトルとキャプションフィールドもありますか?翻訳もそこにあるはずです。

ここでは、使用している翻訳モジュールに関して、非常にあいまいで一般的です。最終的には独自の翻訳モジュールを使用することになるかもしれません-おそらくこれが事実です。 Drupalでこれまでに見たすべての翻訳モデル(D7の時点で、まだD8を見ていません)は、事前対応ではなく、事後対応です。

一言で言えば

理論的には、必要なものを構築するためのツールがあり、エンティティはすべてを結び付ける主要なコンポーネントです。-データ(翻訳文字列)、-ターゲット言語。エンティティ自体、たとえばできれば分類語彙にある必要はありません。または、他のエンティティの一般的な分類法も同様です。 - 環境。エンティティが表示されるURL。 URLにはトークンが含まれ、トークンはターゲット言語の分類法を参照します。

すべてのproductエンティティを取得し、URL aliasフィールドに移動して、分類トークンを取得し、可能なすべての用語の組み合わせを循環し、すべてを提示します。非常に大きな醜いフォーム-またはAJAX-およびマルチステップフォーム(そのようなもの)を使用して、現在ログインしているユーザーが製品のさまざまな言語を翻訳するため、現在のユーザーへの組み合わせ200、それらをデータベースのどこかに保存します

データベースのどこかに、エンティティのフィールドAPIフィールド、各エンティティに属する設定フィールド(正確にはフィールドAPIではありませんが、データを保持できます)、またはこのために使用する個別のテーブルがあります。 Entityにデータを保存すると、コードとデータの両方を整然と簡単に保つことができると思います。


Building It:可能な解決策

  • D8MI (Drupal 8多言語イニシアチブ)
  • カスタムコード:「インデックス」翻訳は、t()によってテンプレートで利用可能になり、利用可能なバンドルとそれらに関連するテーマフックの実装をプログラムでクエリしてレンダリングします。

疑似コード

Foreachエンティティ(タイプxの)、
すべての言語を検索します(製品に関連する分類法またはコア言語)、
エンティティをレンダリングし、
-それを検出するためt()翻訳文字列
-renderは、製品データモデル自体ではなく、製品の多言語プレゼンテーションレイヤーを処理するtheme()を呼び出します。

結果:
-各言語でエンティティテンプレートをレンダリングする最初の呼び出しは、各呼び出しのデフォルトの言語実装を返します。
-t()テンプレートのパラメータがDrupalにキャッシュされ、翻訳の準備ができました(各製品ではなく各言語インスタンスに対して)インスタンス)。
-「translator」の役割を持つユーザーは、翻訳インターフェースに移動して、各言語で使用可能なすべてのt()パラメータを翻訳できます。
-サイトの所有者は、顧客が各製品ページにアクセスするのを待つ必要も、手動で各製品ページにアクセスする必要もありません。これは、プログラムによって行われたためです。

未解決の質問:
-コンテキストとは何ですか? 「製品」エンティティバンドルごとにtheme()へのプログラムによる呼び出しを行うと、呼び出しが行われた場所が記録されますか?ノードのURLを記録していますか? 「コンテキスト」を変更できますか?コンテキストはどこに記録されていますか? 「動的」テンプレートがある場合、つまり製品ごとに複数のテンプレートがある場合、およびそれらのバリエーションを検出する方法はどうなりますか?

いつものように、理論化と疑似コードはブレーンストーミングにのみ適しています。しかし、開発段階では、プロトタイピングを開始するまで、実際に何に直面しているのかほとんどわかりません。いくつかの制約、考えられる解決策、考えられる問題または質問を作成したので、ここで概念実証または実用的なプロトタイプの実装に進むことができます。上記の未解決の質問のいくつかはこの方法でしか回答できません。プロトタイプの初期段階(成功または失敗に関係なく)で、これらの質問のいくつかに回答し始めるか、アプローチを完全に変更できます。お待ちください〜

5
amateur barista

同じシナリオを再現するために、ローカリゼーションクライアントとエンティティ変換モジュールをもう少し使いました。この回答は以前の回答とはまったく異なるため、別のコメントとして追加します。

  1. 1つまたは最初のノードの言語に追加された翻訳は、すべてのノードで使用できます。

    次に例を示します。

    • Nid 200と同じタイプの新しい製品を追加し、plの翻訳の新しいノード(たとえばpl/product/204)にアクセスすると、pl/product/200に同じ翻訳文字列が表示されます。

    • 唯一の違いは、ローカリゼーションクライアントに表示されないことです。モジュールの課題キューでこの機能を要求できますが、翻訳は現在のページに固有ではなく、すべてのページ(つまり、pl/product/200とpl/product/204の両方)に影響を与えるため、さらに混乱が生じます。

    • 2人の異なる人によって作成された2つのノードで、後者が翻訳を変更したい場合は、インターフェース翻訳を使用する必要があります。

  2. 同じノードで最初にアクセスする言語のローカリゼーションクライアントで文字列を利用できます

    次に例を示します。

    • 新しい製品nid 199を追加し、「pl」言語の翻訳(nid 200)と「rs」言語の翻訳(nid 201)を作成すると、「rs」ページではなく「pl」ページでのみ文字列を表示できます。繰り返しますが、これはローカリゼーションクライアントモジュールの制限のように見えます。
2
vijaycs85

翻訳テンプレート抽出子 を使用したAFAIKでは、t()関数へのすべての呼び出し内で文字列を抽出できます。

翻訳テンプレートエクストラクタは、DrupalのWebベースおよびコマンドラインのGettext翻訳テンプレートエクストラクタインターフェースと、翻訳可能な文字列および翻訳エラーを検索するための再利用可能なAPIを提供します。このツールは内部で使用されます http://localize.drupal.org/ にあり、Drupal.orgプロジェクトリリースの解析マシンとしても機能します。

これを読む モジュールの翻訳方法は?

1

テンプレートまたはモジュールファイルレベルで翻訳文字列を追加するアプローチは、インターフェース翻訳UIでは機能しますが、ローカリゼーションクライアントでは機能しません。

明らかに、製品200のロシア語バージョンがある場合、それは新しいノードになります。たとえば、ローカリゼーションクライアントを使用して翻訳できる/ ru/product/201などです。

ちょっと考えてみてください。インターフェース翻訳UIですべての言語に翻訳できる文字列を探し、本当に必要なときに製品レベルの翻訳を依頼してください。次に例を示します。

「これはカテゴリーbarの製品fooです」

「foo」と「bar」以外が一般的であると確信している場合は、

$vars['product_title'] = t('This is product @product of category @category')

前処理中。

.tpl.phpファイルは

<?php t($product_title, array('@product' => t('foo'),  '@category' => t('bar')); ?>
1
vijaycs85