Всегда ли плохо передавать переменную через 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() (по умолчанию). Есть какие-нибудь комментарии по поводу того, что это хороший или плохой стиль?

Author: Clive, 2011-08-16

3 answers

Первым аргументом 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.'); когда он находит значение, зависящее от времени выполнения, например значение переменной, скрипт не может понять, какая строка должна быть переведена, так как переменная может содержать другое значение каждый раз, когда выполняется код. На самом деле, http://localize.drupal.org сообщает о предупреждении, аналогичном следующему, в случае, если аргумент для t() не является буквальной строкой:

Первым параметром для t() должна быть литеральная строка. Там там не должно быть переменных, конкатенаций, констант или других нелитеральных строк. В t($filter['name']) в модуле customfilter/customfilter.module в строке 30.

Если вы передаете динамическое значение в 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;
}

Отчет, вызвавший удаление вызовов t() из любых реализаций ядра Drupal hook_schema(), Удаляет t() из всех описаний схемы, который был открыт веб-чик (соавтор Drupal 7).

В Сегеде у нас была большая долгая дискуссия о t() вокруг описаний схем, и все за столом (включая Дриса) согласились с тем, что t() должны быть удалены из этих описаний. Они все портят, потому что t() недоступен так рано, и люди обсуждали, что никто не собирается тратить время на перевод технических описаний вещей, и это действительно не имеет смысла, так как мы также не например, перевести комментарии к коду.

В статье о преобразовании модуля Drupal 6 в Drupal 7 есть специальный абзац: Описания схем больше не переводятся.

 18
Author: kiamlaluno, 2014-02-21 11:24:34

Это неизменяемые строки, поэтому хорошо пропускать их через t(). Есть некоторые изменения в системе t() для подобных вещей, но я не уверен, что это произойдет в D8.

В настоящее время это плохо, только если вы передадите что-то вроде t($count . ' books'), где $count может принимать любое значение, так как это создаст слишком много строк для перевода.

 2
Author: jcisio, 2012-03-08 01:19:36

Однако можно использовать t() вокруг переменной и для того, чтобы она работала. Я сделал это с помощью $title в page.tpl.php .

РЕДАКТИРОВАТЬ: Возможно, строки не переводятся, но их можно использовать для переопределения строк.

 -1
Author: naomi, 2014-02-21 09:47:21