The first argument of t()
needs to be a literal string, which excludes:
- variables, even the parameters of a function:
t($description)
- a concatenation of strings:
t('If you want to add a link, click on' . '<a href="http://example.com">this link</a>.')
- the value returned from a function:
t(get_menu_description())
- a constant:
t(MYMODULE_MY_WIDGET_TITLE)
, t(MyClass::WIDGET_TITLE)
The reason is that, apart few specific hooks (e.g. hook_menu()
, hook_perm()
, hook_permission()
), the string to translate are found from a script that scan the code of a module, looking for code such as t('This is an example.')
; when it finds a value that depends from runtime, such as the value of a variable, the script is not able to understand which is the string that needs to be translated, as a variable could contain a different value each times the code gets executed.
In fact, http://localize.drupal.org reports a warning similar to the following one, in the case the argument for t()
is not a literal string:
The first parameter to t()
should be a literal string. There should be no variables, concatenation, constants or other non-literal strings there. At t($filter['name'])
in customfilter/customfilter.module on line 30.
If you are passing a dynamic value to t()
, the script that extracts the strings to translate will not extract any value, in that case; the effect is the argument passed to t()
will not be translated, which has the same effect of not using t()
and using the dynamic output directly in the user interface. The only case for which the string will be translated is when the dynamic string is equal to the literal string a function passes to t()
. Suppose, for example, that you have a library not thought for Drupal, which contains a function returning the name of the current month. With the following code, the value returned from that function would be translated.
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()
doesn't need to be called, nor to return any value. When the code of the module will be parsed, the call to t()
will be found from the code that looks for literal strings passed to t()
.
Translating the description given for a database table and its fields is then not something that you should do, as none of the Drupal core modules do that; for example, node_schema() contains the following code:
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;
}
The report that caused the removal of the calls to t()
from any Drupal core implementations of hook_schema()
is Remove t() from all schema descriptions, which has been open by webchick (Drupal 7 co-maintainer).
In Szeged, we had a big long discussion about t()
around the schema descriptions and it was the consensus of everyone at the table (who included Dries) that t()
s should be removed from these descriptions. They mess up things because t()
isn't available that early, and people discussed that no one is going to take the time to translate technical descriptions of stuff, and it doesn't really make sense since we also don't translate code comments, for example.
The article about converting a Drupal 6 module to Drupal 7, has a dedicated paragraph: Schema descriptions are no longer translated.