¿Siempre es malo pasar una variable a través de t ()?

13

Tengo una pequeña función auxiliar para mi 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),
  );
}

Y luego puedo usar 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)'),
      ...
    ),
  );
}

Sé que la directriz no es pasar variables, t()pero esto parece muy similar a cómo el sistema de menús pasa el título de la devolución de llamada t()(de forma predeterminada). ¿Algún comentario sobre este buen o mal estilo?

Andy
fuente

Respuestas:

17

El primer argumento de t()debe ser una cadena literal, que excluye:

  • variables, incluso los parámetros de una función: t($description)
  • una concatenación de cuerdas: t('If you want to add a link, click on' . '<a href="http://example.com">this link</a>.')
  • El valor devuelto por una función:t(get_menu_description())
  • una constante: t(MYMODULE_MY_WIDGET_TITLE),t(MyClass::WIDGET_TITLE)

La razón es que, aparte de algunos ganchos específicos (p hook_menu(). Ej . hook_perm(), hook_permission()), La cadena a traducir se encuentra en un script que escanea el código de un módulo, buscando código como t('This is an example.'); cuando encuentra un valor que depende del tiempo de ejecución, como el valor de una variable, el script no puede entender cuál es la cadena que debe traducirse, ya que una variable podría contener un valor diferente cada vez que se ejecuta el código. De hecho, http://localize.drupal.org informa una advertencia similar a la siguiente, en el caso de que el argumento t()no sea una cadena literal:

El primer parámetro t()debe ser una cadena literal. No debe haber variables, concatenación, constantes u otras cadenas no literales allí. En t($filter['name'])customfilter / customfilter.module en la línea 30.

Si está pasando un valor dinámico a t(), el script que extrae las cadenas para traducir no extraerá ningún valor, en ese caso; el efecto es que el argumento pasado t()no se traducirá, lo que tiene el mismo efecto de no usar t()y usar la salida dinámica directamente en la interfaz de usuario. El único caso para el que se traducirá la cadena es cuando la cadena dinámica es igual a la cadena literal a la que pasa una función t(). Supongamos, por ejemplo, que tiene una biblioteca no pensada para Drupal, que contiene una función que devuelve el nombre del mes actual. Con el siguiente código, el valor devuelto por esa función se traduciría.

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()no necesita ser llamado, ni devolver ningún valor. Cuando se analiza el código del módulo, la llamada a t()se encontrará en el código que busca las cadenas literales pasadas a t().

Traducir la descripción dada para una tabla de base de datos y sus campos no es algo que deba hacer, ya que ninguno de los módulos principales de Drupal lo hace; por ejemplo, node_schema () contiene el siguiente 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;
}

El informe que provocó la eliminación de las llamadas t()desde cualquier implementación central de Drupal hook_schema()es Remove t () de todas las descripciones de esquema , que ha sido abierto por webchick (co-mantenedor de Drupal 7).

En Szeged, tuvimos una gran discusión sobre t()las descripciones del esquema y fue el consenso de todos en la mesa (que incluía a Dries) lo que t()debería eliminarse de estas descripciones. Arruinan las cosas porque t()no están disponibles tan temprano, y la gente discutió que nadie se tomará el tiempo para traducir descripciones técnicas de las cosas, y realmente no tiene sentido ya que tampoco traducimos comentarios de código, por ejemplo.

El artículo sobre la conversión de un módulo Drupal 6 a Drupal 7 tiene un párrafo dedicado: las descripciones de los esquemas ya no se traducen .

kiamlaluno
fuente
2
Más información sobre el uso de t () en los ganchos de instalación / actualización: drupal.org/node/322731
AyeshK
2

Son cadenas invariables, por lo que es bueno pasarlas t(). Hay algunas revisiones del sistema t () para cosas como esta, pero no estoy seguro de que suceda en D8.

Actualmente, solo es malo si pasa algo como t($count . ' books')donde $countpuede tomar cualquier valor, ya que generará demasiadas cadenas para la traducción.

jcisio
fuente
-1

Sin embargo, es posible usar t () alrededor de una variable y que funcione. Lo hice con $ title en page.tpl.php.

EDITAR: Quizás las cadenas no se traducen, pero se pueden usar para anulaciones de cadenas.

naomi
fuente
1
Vea la respuesta de kiamlaluno para saber por qué es una mala idea.
Andy
La respuesta de kiamlaluno parece decir que la cadena no se traducirá. Pero otro uso de t () es habilitar anulaciones de cadenas. Puedo confirmar que eso funciona con variables.
naomi
1
@naomi Sí, funcionará. Pero si tiene habilitadas las traducciones, todos los títulos aprobados a través de t () terminarán en la lista de cadenas de traducción. No debe usar anulaciones de cadenas para cambiar los títulos de nodo IMO. Cree un campo y cambie el título del nodo al valor del campo en un hook_preprocess_node o página. (También puede usar hook_node_load o cualquier gancho relacionado también)
AyeshK