Est-il toujours mauvais de passer une variable via t ()?

13

J'ai une petite fonction d'aide pour mon 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),
  );
}

Et puis je peux l'utiliser quelque chose comme:

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

Je sais que la ligne directrice n'est pas de transmettre des variables, t()mais cela semble très similaire à la façon dont le système de menus transmet le titre du rappel t()(par défaut). Avez-vous des commentaires sur le fait que ce soit bon ou mauvais style?

Andy
la source

Réponses:

17

Le premier argument de t()doit être une chaîne littérale, ce qui exclut:

  • variables, même les paramètres d'une fonction: t($description)
  • une concaténation de chaînes: t('If you want to add a link, click on' . '<a href="http://example.com">this link</a>.')
  • la valeur renvoyée par une fonction:t(get_menu_description())
  • une constante: t(MYMODULE_MY_WIDGET_TITLE),t(MyClass::WIDGET_TITLE)

La raison en est que, à l' exception de quelques crochets spécifiques (par exemple hook_menu(), hook_perm(), hook_permission()), la chaîne à traduire sont à partir d' un script trouvé qui analyse le code d'un module, à la recherche de code tel que t('This is an example.'); lorsqu'il trouve une valeur qui dépend de l'exécution, comme la valeur d'une variable, le script n'est pas en mesure de comprendre quelle est la chaîne qui doit être traduite, car une variable peut contenir une valeur différente à chaque exécution du code. En fait, http://localize.drupal.org signale un avertissement similaire au suivant, dans le cas où l'argument pour t()n'est pas une chaîne littérale:

Le premier paramètre à t()doit être une chaîne littérale. Il ne doit pas y avoir de variables, de concaténation, de constantes ou d'autres chaînes non littérales. À t($filter['name'])dans customfilter / customfilter.module à la ligne 30.

Si vous transmettez une valeur dynamique à t(), le script qui extrait les chaînes à traduire n'extrayera aucune valeur, dans ce cas; l'effet est que l'argument transmis t()ne sera pas traduit, ce qui a le même effet de ne pas utiliser t()et d'utiliser la sortie dynamique directement dans l'interface utilisateur. Le seul cas pour lequel la chaîne sera traduite est lorsque la chaîne dynamique est égale à la chaîne littérale à laquelle une fonction passe t(). Supposons, par exemple, que vous ayez une bibliothèque non pensée pour Drupal, qui contient une fonction renvoyant le nom du mois en cours. Avec le code suivant, la valeur renvoyée par cette fonction serait traduite.

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'a pas besoin d'être appelé, ni de renvoyer de valeur. Lorsque le code du module sera analysé, l'appel à t()sera trouvé à partir du code qui recherche les chaînes littérales passées à t().

La traduction de la description donnée pour une table de base de données et ses champs n'est alors pas quelque chose que vous devriez faire, car aucun des modules de base Drupal ne le fait; par exemple, node_schema () contient le code suivant:

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

Le rapport qui a provoqué la suppression des appels à t()de toutes les implémentations principales de Drupal hook_schema()est Supprimer t () de toutes les descriptions de schéma , qui a été ouvert par webchick (co-responsable Drupal 7).

À Szeged, nous avons eu une longue discussion t()autour des descriptions de schéma et c'était le consensus de tout le monde à la table (qui comprenait Dries) que les t()s devraient être supprimés de ces descriptions. Ils gâchent les choses parce qu'ils t()ne sont pas disponibles si tôt, et les gens ont dit que personne ne prendrait le temps de traduire les descriptions techniques des choses, et cela n'a pas vraiment de sens puisque nous ne traduisons pas non plus les commentaires de code, pour exemple.

L'article sur la conversion d'un module Drupal 6 en Drupal 7, contient un paragraphe dédié: les descriptions de schéma ne sont plus traduites .

kiamlaluno
la source
2
Plus d'informations sur l'utilisation de t () dans les hooks d'installation / mise à jour: drupal.org/node/322731
AyeshK
2

Ce sont des chaînes invariables, il est donc bon de les passer t(). Il y a une refonte du système t () pour des choses comme ça, mais je ne suis pas sûr que cela se produira en D8.

Actuellement, cela n'est mauvais que si vous passez quelque chose comme t($count . ' books')$countpeut prendre n'importe quelle valeur, car cela générera trop de chaîne pour la traduction.

jcisio
la source
-1

Il est cependant possible d'utiliser t () autour d'une variable, et pour que cela fonctionne. Je l'ai fait avec $ title dans page.tpl.php.

EDIT: Peut-être que les chaînes ne sont pas traduites, mais elles peuvent être utilisées pour les remplacements de chaînes.

naomi
la source
1
Voir la réponse de kiamlaluno pour savoir pourquoi c'est une mauvaise idée.
Andy
La réponse de kiamlaluno semble dire que la chaîne ne sera pas traduite. Mais une autre utilisation de t () est d'activer les remplacements de chaîne. Je peux confirmer que cela fonctionne avec des variables.
naomi
1
@naomi Oui, cela fonctionnera. Mais si vous avez activé les traductions, tous les titres passés par th (t) se retrouveront dans la liste des chaînes de traduction. Vous ne devez pas utiliser des remplacements de chaîne pour modifier les titres de noeud IMO. Créez un champ et modifiez le titre du nœud en valeur du champ dans un hook_preprocess_node ou une page. (Vous pouvez également utiliser hook_node_load ou tout autre crochet connexe)
AyeshK