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


14

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

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

ユーザーがローカリゼーションクライアントモジュールのオンサイト翻訳ツールを使用して翻訳できるようにする必要があります。そうすれば、ユーザーは実際に翻訳対象を確認し、適切なコンテキストで翻訳できます。ソースの場所をに設定する/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 (テーマデータを生成するモジュール)

しかし、それは翻訳ツールに対してのみ不可視になりました。

Localization clientのバグではないと確信しています。この文字列が発生したと伝えられている文字列を表示します。そして、それはDrupal 7翻訳システムにとっても「それが機能する方法」であるようです-すでに議論され報告されており、何も変わりませんでした。ですから、これはバグレポートではなく、私たちがやらなければならないことをどうやって扱うかを尋ねるだけです。


私はデータモジュールの操作関係のないテキストについて話しています。製品を翻訳したくありません。製品イメージギャラリーテンプレートの前-次のように、製品自体とは関係のないテンプレート文字列だけです。

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


あなたが望むものを完全に理解したかどうかはわかりませんが、すべての言語でサイトをクロールするだけで十分でしょうか?あなたは例えばを使用することができます xmlsitemapを使用して複数の言語でリンクを生成し、それからwget何でも使用します。ハックが、あなたはそれが許可されたと言った(:
アンディ14

@Andy Localization Clientを使用すると、ユーザーはページの下部にあるバーを開いて、そのページが表示されたときにそのページに直接表示されるテキストを翻訳できます。すべてのテキストをエクスポートできますが、それがポイントではありません。
モウォ14

1
drupal_set_message()およびdpm()から、たとえばpage.tpl.phpから呼び出された場合、これらのメッセージは次のリクエストのためにキューに入れられることを覚えています。これは、通常、メッセージが処理された後、テンプレートはリクエストのかなり遅い時間に処理されるためです。同様のことは、t()とローカリゼーションクライアントの場合です。
ドンキホーテ14

いい質問ですね。いい問題だ。
アマチュアバリスタ14

単なる提案...ユーザーが任意の言語でtpl t()文字列をいつでも翻訳できるようにしたい場合は、これらの文字列を翻訳テンプレート抽出ツールdrupal.org/project/potx)で抽出し、オリジナルの.po、Poeditなどのツールを使用して翻訳できますか?(poedit.net)。あなたはいくつかの静的のものとしてこれらの文字列を提示すると、ジョブは各翻訳者によって一度に行われるでしょう...
古城

回答:


5

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

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


クローラー

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


問題

  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を取得すると、データベースにアクセスして製品200を検索し、既存のpl翻訳を取得します。その製品のタイトルとキャプションのフィールドもありますか?翻訳もそこにあるはずです。

ここで使用している翻訳モジュールに関して、私は非常に曖昧で一般的です。独自の翻訳モジュールを使用することになる可能性が非常に高くなります-これはほとんどの場合です。これまでにDrupalで見たすべての翻訳モデル(D7の時点ではまだD8を見ていない)は、リアクティブであり、プロアクティブではありません。

手短に

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

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

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


構築:可能な解決策

  • D8MI(Drupal 8 Multilingual Initiative)
  • カスタムコード:利用可能なバンドルおよび関連するテーマフックの実装をプログラムでクエリおよびレンダリングすることにより、t()によってテンプレートで利用可能になる「インデックス」翻訳。

擬似コード

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

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

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

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


1
でも、全体の記事を読むことなく、答えのようなものは、upvoteに値する
OV

要点は、Drupal 7に必要なことだけを実行していると主張するツールが既に存在するということです。これは、Drupalがこれらの文字列を不適切なメタデータで保存することの問題です。しかし、文字列が収集されたら、dbのメタデータを変更できます。問題ありません。設定するものを知る必要があるだけなので、ツールはそれを見ることができます。または、少なくともそれが私が必要とするものだと信じていました。そして最も重要なことは、製品を翻訳したくないことです。製品イメージギャラリーテンプレートの前-次のように、製品自体とは関係のないテンプレート文字列だけです。
モウォ

2

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

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

    次に例を示します。

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

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

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

  2. 文字列は、同じノードにアクセスする最初の言語のローカリゼーションクライアントで使用可能です

    次に例を示します。

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

1

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

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

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

「これはカテゴリバーの製品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')); ?>

それは詳細だtitleイメージローテータの矢印のためのテキスト。私のモジュールは、テーマが15個の画像を表示する方法を気にしません。また、テーマには一度に5つが表示され、「前」と「次」の矢印が必要でaltありtitle、それらは翻訳が必要です。フロントエンドが変更されるたびにモジュールを変更することは可能ですが、もちろん必要ではありません。これらの文字列は、モジュール自体とは関係ありません。最後になりましたが、テーマの変更された文字列に気付かないかもしれません。または、それらをモジュールに移行することはできません。
モウォ14

私見、このケースは、ローカリゼーションクライアントの代わりに、インターフェイス変換UIで処理する必要があります。
vijaycs85 14

ローカリゼーションクライアントの目的は、「問題が発生したときにサイトの翻訳を修正する」ことです。-なぜテンプレートファイルに適用すべきではないのですか?tplの文字列は、表示されるコンテキストに敏感です。
モウォ14

1

私の知る限り翻訳テンプレート抽出あなたがにすべてのあなたの呼び出し内の文字列を抽出することができますt()機能。

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

このモジュールを翻訳する方法をお読みください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.