web-dev-qa-db-ja.com

t()を通じて変数を渡すことは常に悪いことですか?

私は私のhook_schemaの小さなヘルパー関数を持っています:

_function _bbcmap_schema_asr_field($description) {
  return array(
    'type' => 'int',
    'unsigned' => TRUE,
    'size' => 'small', // Up to ~66k with MySQL (equivalent up to ~660.00 adjusted)
    'not null' => FALSE,
    'description' => t($description),
  );
}
_

そして、私はそれを次のように使うことができます:

_/**
 * Implements hook_schema().
 */
function bbcmap_schema() {
  $schema['la_data'] = array(
    'fields' => array(
      ...
      'mort_asr_male' =>    _bbcmap_schema_asr_field('The age standardised mortality amongst men (fixed point with scale factor 1/100)'),
      'mort_asr_female' =>  _bbcmap_schema_asr_field('The age standardised mortality amongst women (fixed point with scale factor 1/100)'),
      'incid_asr_male' =>   _bbcmap_schema_asr_field('The age standardised incidence amongst men (fixed point with scale factor 1/100)'),
      'incid_asr_female' => _bbcmap_schema_asr_field('The age standardised incidence amongst women (fixed point with scale factor 1/100)'),
      ...
    ),
  );
}
_

ガイドラインはt()を介して変数を渡すことではないことを知っていますが、これはメニューシステムがt()を介してコールバックのタイトルを渡す方法と非常によく似ています(デフォルト)。これが良いスタイルか悪いスタイルかについてのコメントはありますか?

13
Andy

t()の最初の引数はリテラル文字列である必要があります。

  • 変数、関数のパラメーターも:t($description)
  • 文字列の連結:t('If you want to add a link, click on' . '<a href="http://example.com">this link</a>.')
  • 関数から返される値:t(get_menu_description())
  • 定数:t(MYMODULE_MY_WIDGET_TITLE)t(MyClass::WIDGET_TITLE)

その理由は、いくつかの特定のフック(hook_menu()hook_perm()hook_permission()など)を除いて、翻訳する文字列はモジュールのコードをスキャンするスクリプトから見つけられるためです。 t('This is an example.')などのコードを探します。変数の値など、ランタイムに依存する値が見つかると、スクリプトは、コードが実行されるたびに変数に異なる値が含まれる可能性があるため、どの文字列を変換する必要があるかを理解できません。実際、t()の引数がリテラル文字列でない場合、 http://localize.drupal.org は次のような警告を報告します。

t()の最初のパラメーターはリテラル文字列でなければなりません。そこには、変数、連結、定数、その他の非リテラル文字列があってはなりません。 30行目のcustomfilter/customfilter.moduleのt($filter['name'])にあります。

動的な値をt()に渡す場合、翻訳する文字列を抽出するスクリプトは値を抽出しません。その結果、t()に渡された引数は変換されません。これは、t()を使用せず、ユーザーインターフェイスで動的出力を直接使用するのと同じ効果があります。文字列が翻訳される唯一のケースは、動的文字列が関数がt()に渡すリテラル文字列と等しい場合です。たとえば、現在の月の名前を返す関数が含まれているDrupalに対応していないライブラリがあるとします。次のコードでは、その関数から返された値が変換されます。

_function mymodule_calendar_page_title() {
  return t(Calendar::getCurrentMonth());
}

function mymodule_calendar_translations() {
  $translations = array(
    t('January'),
    t('February'),
    t('March'),
    t('April'),
    t('May'),
    t('June'),
    t('July'),
    t('August'),
    t('September'),
    t('October'),
    t('November'),
    t('December'),
  );
}
_

mymodule_calendar_translations()を呼び出す必要も、値を返す必要もありません。モジュールのコードが解析されると、t()に渡されたリテラル文字列を探すコードからt()への呼び出しが見つかります。

Drupalコアモジュールはそれを行わないため、たとえば node_schema() には次のコードが含まれます。

_function node_schema() {
  $schema['node'] = array(
    'description' => 'The base table for nodes.', 
    'fields' => array(
      'nid' => array(
        'description' => 'The primary identifier for a node.', 
        'type' => 'serial', 
        'unsigned' => TRUE, 
        'not null' => TRUE,
      ), 
      'vid' => array(
        'description' => 'The current {node_revision}.vid version identifier.', 
        'type' => 'int', 
        'unsigned' => TRUE, 
        'not null' => TRUE, 
        'default' => 0,
      ), 
      // …
    );
    // …
  );

  // …

  return $schema;
}
_

Drupal t()のコア実装からのhook_schema()への呼び出しの削除を引き起こしたレポートは Remove t()すべてのスキーマの説明から 、これは webchick (Drupal 7共同メンテナ)が開いています。

セゲドでは、スキーマの説明に関してt()について長い長い議論があり、t()をこれらの説明から削除する必要があることは、テーブルの全員(Driesを含む)のコンセンサスでした。 t()はまだ利用できず、スタッフは技術的な説明を翻訳するのに時間をかけるつもりはないことを人々は話しました。たとえば、コードのコメントを翻訳します。

Drupal 6モジュールからDrupal 7への変換)に関する記事には、専用の段落があります: スキーマの説明は翻訳されなくなりました

17
kiamlaluno

これらは不変の文字列なので、t()を介して渡すとよいでしょう。このようなもののためにt()システムのオーバーホールがいくつかありますが、D8で起こるかどうかはわかりません。

現在、t($count . ' books') where $countは、翻訳のために生成される文字列が多すぎるため、任意の値を取ることができます。

2
jcisio