Всегда ли плохо передавать переменную через t ()?

13

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

Энди
источник

Ответы:

17

Первый аргумент 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()- это Remove t () из всех описаний схемы , который был открыт webchick (со-сопровождающий Drupal 7).

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

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

киамлалуно
источник
2
Подробнее об использовании t () в хуках
AyeshK
2

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

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

jcisio
источник
-1

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

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

Naomi
источник
1
Посмотрите ответ kiamlaluno, почему это плохая идея.
Энди
Кажется, в ответ kiamlaluno говорится, что строка не будет переведена. Но другое использование t () - включить переопределения строк. Я могу подтвердить, что это работает с переменными.
Наоми
1
@naomi Да, это будет работать. Но если у вас включен перевод, все переданные thro t () заголовки попадут в список строк перевода. Вы не должны использовать переопределения строк для изменения заголовков узлов IMO. Создайте поле и измените заголовок узла на значение поля в hook_preprocess_node или странице. (Вы также можете использовать hook_node_load или любой связанный хук тоже)
AyeshK