É sempre ruim passar uma variável por t ()?

13

Eu tenho uma pequena função auxiliar para o meu 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),
  );
}

E então eu posso usá-lo algo como:

/**
 * 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)'),
      ...
    ),
  );
}

Eu sei que a diretriz não é passar variáveis, t()mas isso parece muito semelhante ao modo como o sistema de menus passa o título do retorno de chamada t()(por padrão). Algum comentário sobre esse estilo ser bom ou ruim?

Andy
fonte

Respostas:

17

O primeiro argumento de t()precisa ser uma sequência literal, que exclui:

  • variáveis, até os parâmetros de uma função: t($description)
  • uma concatenação de strings: t('If you want to add a link, click on' . '<a href="http://example.com">this link</a>.')
  • o valor retornado de uma função:t(get_menu_description())
  • uma constante: t(MYMODULE_MY_WIDGET_TITLE),t(MyClass::WIDGET_TITLE)

A razão é que, além alguns ganchos específicas (por exemplo hook_menu(), hook_perm(), hook_permission()), a seqüência de traduzir são encontrados a partir de um script que ler o código de um módulo, à procura de código, como t('This is an example.'); quando encontra um valor que depende do tempo de execução, como o valor de uma variável, o script não consegue entender qual é a string que precisa ser traduzida, pois uma variável pode conter um valor diferente cada vez que o código é executado. De fato, http://localize.drupal.org relata um aviso semelhante ao seguinte, caso o argumento para t()não seja uma sequência literal:

O primeiro parâmetro para t()deve ser uma sequência literal. Não deve haver variáveis, concatenação, constantes ou outras cadeias não literais lá. Em t($filter['name'])em customfilter / customfilter.module na linha 30.

Se você estiver passando um valor dinâmico t(), o script que extrai as seqüências a serem traduzidas não extrairá nenhum valor, nesse caso; o efeito ao qual o argumento transmitido t()não será convertido, o que tem o mesmo efeito de não usar t()e usar a saída dinâmica diretamente na interface do usuário. O único caso para o qual a string será convertida é quando a string dinâmica é igual à string literal à qual uma função passa t(). Suponha, por exemplo, que você tenha uma biblioteca não pensada para o Drupal, que contém uma função retornando o nome do mês atual. Com o código a seguir, o valor retornado dessa função seria convertido.

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()não precisa ser chamado nem retornar nenhum valor. Quando o código do módulo será analisado, a chamada para t()será encontrada no código que procura por cadeias literais passadas para t().

Traduzir a descrição fornecida para uma tabela de banco de dados e seus campos não é algo que você deve fazer, pois nenhum dos módulos principais do Drupal faz isso; por exemplo, node_schema () contém o seguinte código:

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;
}

O relatório que causou a remoção das chamadas t()de quaisquer implementações principais do Drupal hook_schema()é o Remove t () de todas as descrições de esquema , abertas pelo webchick (co-mantenedor do Drupal 7).

Em Szeged, tivemos uma grande e longa discussão sobre t()as descrições de esquema e foi o consenso de todos na mesa (que incluíram Dries) que t()s devem ser removidos dessas descrições. Eles estragam as coisas porque t()não estão disponíveis tão cedo, e as pessoas discutiram que ninguém vai gastar tempo para traduzir descrições técnicas de coisas, e isso realmente não faz sentido, pois também não traduzimos comentários de código, por exemplo.

O artigo sobre a conversão de um módulo Drupal 6 em Drupal 7, possui um parágrafo dedicado: As descrições de esquema não são mais traduzidas .

kiamlaluno
fonte
2
Mais informações sobre o uso de t () em instalar / ganchos de atualização: drupal.org/node/322731
AyeshK
2

Eles são invariáveis, então é bom passar por eles t(). Há alguma revisão do sistema t () para coisas como essa, mas não tenho certeza se isso acontecerá no D8.

Atualmente, só é ruim se você passar algo como t($count . ' books')where $countpode ter algum valor, pois isso gerará muitas strings para a tradução.

jcisio
fonte
-1

No entanto, é possível usar t () em torno de uma variável e fazer com que ela funcione. Eu fiz isso com $ title em page.tpl.php.

EDIT: Talvez as strings não sejam traduzidas, mas elas podem ser usadas para substituições de strings.

naomi
fonte
1
Veja a resposta de kiamlaluno para saber por que é uma má ideia.
217 Andy
A resposta de kiamlaluno parece estar dizendo que a string não será traduzida. Mas outro uso para t () é ativar substituições de string. Posso confirmar que isso funciona com variáveis.
naomi
1
@naomi Sim, vai funcionar. Mas se você tiver as traduções ativadas, todos os títulos passados ​​através de t () terminarão na lista de strings de tradução. Você não deve usar substituições de seqüência de caracteres para alterar os títulos do nó IMO. Crie um campo e altere o título do nó para o valor do campo em um hook_preprocess_node ou página. (Você também pode usar hook_node_load ou qualquer gancho relacionada também)
AyeshK