it-swarm.it

È sempre male passare una variabile attraverso t ()?

Ho una piccola funzione di aiuto per il mio 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 poi posso usarlo in qualche modo:

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

So che la linea guida non è quella di passare le variabili attraverso t() ma questo sembra molto simile a come il sistema di menu passa il titolo del callback attraverso t() (per impostazione predefinita). Qualche commento su questo stile buono o cattivo?

13
Andy

Il primo argomento di t() deve essere una stringa letterale, che esclude:

  • variabili, anche i parametri di una funzione: t($description)
  • una concatenazione di stringhe: t('If you want to add a link, click on' . '<a href="http://example.com">this link</a>.')
  • il valore restituito da una funzione: t(get_menu_description())
  • una costante: t(MYMODULE_MY_WIDGET_TITLE), t(MyClass::WIDGET_TITLE)

Il motivo è che, a parte alcuni hook specifici (ad esempio hook_menu(), hook_perm(), hook_permission()), la stringa da tradurre si trova da uno script che analizza il codice di un modulo, alla ricerca di codice come t('This is an example.'); quando trova un valore che dipende dal runtime, come il valore di una variabile, lo script non è in grado di capire quale sia la stringa che deve essere tradotta, poiché una variabile potrebbe contenere un valore diverso ogni volta che il codice viene eseguito. Infatti http://localize.drupal.org riporta un avvertimento simile al seguente, nel caso in cui l'argomento per t() non sia una stringa letterale:

Il primo parametro su t() dovrebbe essere una stringa letterale. Non dovrebbero esserci variabili, concatenazioni, costanti o altre stringhe non letterali. At t($filter['name']) in customfilter/customfilter.module alla riga 30.

Se si passa un valore dinamico a t(), lo script che estrae le stringhe da tradurre non estrarrà alcun valore, in quel caso; l'effetto è l'argomento passato a t() non verrà tradotto, il che ha lo stesso effetto di non usare t() e di usare l'output dinamico direttamente nell'interfaccia utente. L'unico caso per il quale la stringa verrà tradotta è quando la stringa dinamica è uguale alla stringa letterale che una funzione passa a t(). Supponiamo, ad esempio, di avere una libreria non pensata per Drupal, che contiene una funzione che restituisce il nome del mese corrente. Con il seguente codice, il valore restituito da quella funzione verrebbe tradotto.

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() non ha bisogno di essere chiamato, né di restituire alcun valore. Quando verrà analizzato il codice del modulo, la chiamata a t() verrà trovata dal codice che cerca le stringhe letterali passate a t().

La traduzione della descrizione fornita per una tabella del database e i suoi campi non è quindi qualcosa che dovresti fare, poiché nessuno dei moduli principali Drupal lo fa; per esempio node_schema () contiene il seguente codice:

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

Il rapporto che ha causato la rimozione delle chiamate a t() da qualunque Drupal implementazioni di base di hook_schema() è Rimuovi t() da tutte le descrizioni dello schema , che è stato aperto da webchick (Co-manutentore di Drupal 7).

In Szeged, abbiamo avuto una lunga e lunga discussione su t() attorno alle descrizioni dello schema ed è stato il consenso di tutti al tavolo (incluso Dries) che t() s dovrebbe essere rimosso da queste descrizioni . Fanno casino perché t() non è disponibile così presto e la gente ha discusso sul fatto che nessuno si prenderà il tempo di tradurre descrizioni tecniche di cose, e non ha davvero senso dal momento che anche noi tradurre i commenti in codice, ad esempio.

L'articolo sulla conversione di a Drupal 6 modulo in Drupal 7, ha un paragrafo dedicato: Le descrizioni degli schemi non sono più tradotte .

17
kiamlaluno

Sono stringhe invariabili, quindi è bene passarle attraverso t(). Ci sono alcune revisioni del sistema t() per cose come questa, ma non sono sicuro che accadrà in D8.

Al momento, è un problema solo se passi qualcosa come t($count . ' books') dove $count può assumere qualsiasi valore, poiché genererà troppe stringhe per la traduzione.

2
jcisio