通过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()(默认情况下)传递回调标题的方式非常相似。关于这种风格的好坏有何评论?

Answers:


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'])第30行的customfilter / customfilter.module中。

如果您将动态值传递给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(),已由webchick(Drupal 7共同维护者)打开。

在Szeged中,我们t()围绕架构描述进行了长时间的讨论,t()应该从这些描述中删除s ,这是餐桌上所有人(包括Dries)的共识。他们弄乱了东西,因为那t()是因为太早没有了,人们讨论说没有人会花时间来翻译东西的技术描述,而且这实际上没有任何意义,因为我们也不会翻译代码注释,因为例。

关于将Drupal 6模块转换为Drupal 7的文章有一段专门的段落:模式描述不再翻译


2
有关在安装/更新挂钩中使用t()的更多信息:drupal.org/node/322731
AyeshK 2014年

2

它们是不变的字符串,因此最好通过它们t()。对t()系统进行了一些类似的大修,但我不确定它是否会在D8中发生。

当前,只有传递诸如t($count . ' books')where $count可以获取任何值之类的东西,这才是不好的,因为它将为翻译生成太多的字符串。


-1

但是,可以在变量周围使用t()并使其起作用。我已经在page.tpl.php中用$ title完成了。

编辑:也许字符串不会被翻译,但是它们可用于字符串替代。


1
请参阅kiamlaluno的答案,了解为什么这是一个坏主意。
安迪

kiamlaluno的答案似乎是在说字符串不会被翻译。但是t()的另一个用途是启用字符串覆盖。我可以确认这确实适用于变量。
naomi 2014年

1
@naomi是的,它将起作用。但是,如果启用了翻译,则所有通过t()传递的标题都将最终出现在翻译字符串列表中。您不应使用字符串替代来更改节点标题IMO。创建一个字段,然后在hook_preprocess_node或页面中将节点标题更改为该字段的值。(您也可以使用hook_node_load或任何相关的钩子)
AyeshK 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.