Czy zawsze źle jest przekazać zmienną przez t ()?

13

Mam małą funkcję pomocniczą dla mojej 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),
  );
}

A potem mogę użyć czegoś takiego:

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

Wiem, że wytyczną nie jest przekazywanie zmiennych, t()ale wydaje się to bardzo podobne do sposobu, w jaki system menu przekazuje tytuł wywołania zwrotnego t()(domyślnie). Wszelkie uwagi na temat tego, czy jest to dobry czy zły styl?

Andy
źródło

Odpowiedzi:

17

Pierwszym argumentem t()musi być ciąg literalny, który wyklucza:

  • zmienne, nawet parametry funkcji: t($description)
  • łączenie ciągów: t('If you want to add a link, click on' . '<a href="http://example.com">this link</a>.')
  • wartość zwrócona z funkcji:t(get_menu_description())
  • stały: t(MYMODULE_MY_WIDGET_TITLE),t(MyClass::WIDGET_TITLE)

Powodem jest to, że oprócz kilku specyficznych (np haki hook_menu(), hook_perm(), hook_permission()), łańcuch tłumaczyć znajdują się w skrypcie, które skanują kod modułu, patrząc na kod, takich jak t('This is an example.'); gdy znajdzie wartość zależną od środowiska wykonawczego, taką jak wartość zmiennej, skrypt nie jest w stanie zrozumieć, który ciąg należy przetłumaczyć, ponieważ zmienna może zawierać inną wartość za każdym razem, gdy kod zostanie wykonany. W rzeczywistości http://localize.drupal.org zgłasza ostrzeżenie podobne do następującego, w przypadku gdy argument za t()nie jest ciągiem literalnym:

Pierwszym parametrem t()powinien być ciąg literalny. Nie powinny tam być zmienne, konkatenacja, stałe ani inne łańcuchy nieliteralne. At t($filter['name'])w customfilter / customfilter.module w linii 30.

Jeśli przekazujesz wartość dynamiczną t(), skrypt, który wyodrębnia ciągi do przetłumaczenia, nie wyodrębni żadnej wartości, w takim przypadku; efektem jest przekazany argument, t()który nie zostanie przetłumaczony, co daje taki sam efekt, że nie używa t()i nie używa dynamicznych danych wyjściowych bezpośrednio w interfejsie użytkownika. Jedynym przypadkiem, dla którego ciąg zostanie przetłumaczony, jest ciąg dynamiczny równy literałowi ciągu, do którego przechodzi funkcja t(). Załóżmy na przykład, że masz bibliotekę niepomyślną dla Drupala, która zawiera funkcję zwracającą nazwę bieżącego miesiąca. W przypadku następującego kodu wartość zwracana z tej funkcji zostałaby przetłumaczona.

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()nie trzeba go wywoływać ani zwracać żadnej wartości. Kiedy kod modułu zostanie przeanalizowany, wywołanie to t()zostanie znalezione w kodzie, który szuka literalnych ciągów znaków przekazywanych do t().

Tłumaczenie opisu podanego dla tabeli bazy danych i jej pól nie jest więc czymś, co powinieneś zrobić, ponieważ żaden z podstawowych modułów Drupala tego nie robi; na przykład node_schema () zawiera następujący kod:

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

Raport, który spowodował usunięcie wywołań t()z dowolnej implementacji rdzenia Drupala, hook_schema()to Usuń t () ze wszystkich opisów schematów , które zostały otwarte przez webchicka (współ-opiekuna Drupala 7).

W Szeged mieliśmy długą długą dyskusję na temat t()opisów schematów i to właśnie konsensus wszystkich przy stole (włączając Dries) t()powinien zostać usunięty z tych opisów. Robią bałagan, ponieważ t()nie są dostępne tak wcześnie, a ludzie dyskutują, że nikt nie poświęci czasu na przetłumaczenie technicznych opisów rzeczy, a to nie ma sensu, ponieważ nie tłumaczymy też komentarzy do kodu, ponieważ przykład.

Artykuł o konwertowaniu modułu Drupal 6 na Drupal 7 zawiera dedykowany akapit: Opisy schematów nie są już tłumaczone .

kiamlaluno
źródło
2
Więcej informacji na temat używania t () w hookach
AyeshK
2

Są to ciągi niezmienne, więc dobrze je przekazać t(). Istnieje pewien przegląd systemu t () dla takich rzeczy, ale nie jestem pewien, czy tak się stanie w D8.

Obecnie jest to złe tylko wtedy, gdy podasz coś takiego, t($count . ' books')gdzie $countmożna przyjąć dowolną wartość, ponieważ wygeneruje zbyt wiele ciągów do tłumaczenia.

Jcisio
źródło
-1

Możliwe jest jednak użycie t () wokół zmiennej i jej działanie. Zrobiłem to z $ title w page.tpl.php.

EDYCJA: Być może ciągi nie są tłumaczone, ale można ich użyć do zastąpienia ciągów.

naomi
źródło
1
Zobacz odpowiedź kiamlaluno, dlaczego jest to zły pomysł.
Andy,
Wydaje się, że odpowiedź kiamlaluno mówi, że ciąg nie zostanie przetłumaczony. Ale innym zastosowaniem t () jest włączenie przesłonięcia łańcucha. Mogę potwierdzić, że to działa ze zmiennymi.
naomi
1
@naomi Tak to zadziała. Ale jeśli masz włączone tłumaczenia, wszystkie tytuły przekazane przez thro () znajdą się na liście ciągów tłumaczenia. Nie należy używać przesłonięć ciągów do zmiany tytułów węzłów IMO. Utwórz pole i zmień tytuł węzła na wartość pola w węźle_przygotowania_procesu lub na stronie. (Możesz także użyć hook_node_load lub dowolnego powiązanego
hooka