8.2.x bootstrap.inc t($string, array $args = array(), array $options = array())
8.0.x bootstrap.inc t($string, array $args = array(), array $options = array())
8.1.x bootstrap.inc t($string, array $args = array(), array $options = array())
8.3.x bootstrap.inc t($string, array $args = array(), array $options = array())
4.6.x common.inc t($string, $args = 0)
4.7.x common.inc t($string, $args = 0)
5.x common.inc t($string, $args = 0)
6.x common.inc t($string, $args = array(), $langcode = NULL)
7.x bootstrap.inc t($string, array $args = array(), array $options = array())

Translates a string to the current language or to a given language.

The t() function serves two purposes. First, at run-time it translates user-visible text into the appropriate language. Second, various mechanisms that figure out what text needs to be translated work off t() -- the text inside t() calls is added to the database of strings to be translated. These strings are expected to be in English, so the first argument should always be in English. To enable a fully-translatable site, it is important that all human-readable text that will be displayed on the site or sent to a user is passed through the t() function, or a related function. See the Localization API pages for more information, including recommendations on how to break up or not break up strings for translation.

Translating Variables

You should never use t() to translate variables, such as calling


, unless the text that the variable holds has been passed through t() elsewhere (e.g., $text is one of several translated literal strings in an array). It is especially important never to call


, where $user_text is some text that a user entered - doing that can lead to cross-site scripting and other security problems. However, you can use variable substitution in your string, to put variable text such as user names or link URLs into translated text. Variable substitution looks like this:

$text = t("@name's blog", array('@name' => format_username($account)));

Basically, you can put variables like @name into your string, and t() will substitute their sanitized values at translation time. (See the Localization API pages referenced above and the documentation of format_string() for details about how to define variables in your string.) Translators can then rearrange the string as necessary for the language (e.g., in Spanish, it might be "blog de @name").

Use During Installation Phase

During the Drupal installation phase, some resources used by t() wil not be available to code that needs localization. See st() and get_t() for alternatives.

String context

Matching source strings are normally only translated once, and the same translation is used everywhere that has a matching string. However, in some cases, a certain English source string needs to have multiple translations. One example of this is the string "May", which could be used as either a full month name or a 3-letter abbreviated month. In other languages where the month name for May has more than 3 letters, you would need to provide two different translations (one for the full name and one abbreviated), and the correct form would need to be chosen, depending on how "May" is being used. To facilitate this, the "May" string should be provided with two different contexts in the $options parameter when calling t(). For example:

t('May', array(), array('context' => 'Long month name')
t('May', array(), array('context' => 'Abbreviated month name')

See https://localize.drupal.org/node/2109 for more information.


$string: A string containing the English string to translate.

$args: An associative array of replacements to make after translation. Based on the first character of the key, the value is escaped and/or themed. See format_string() for details.

$options: An associative array of additional options, with the following elements:

  • 'langcode' (defaults to the current language): The language code to translate to a language other than what is used to display the page.
  • 'context' (defaults to the empty context): A string giving the context that the source string belongs to. See @ref sec_context above for more information.

Return value

The translated string.

See also




Related topics

1901 calls to t()
AccessDeniedTestCase::testAccessDenied in modules/system/system.test
ActionLoopTestCase::testActionLoop in modules/simpletest/tests/actions.test
Set up a loop with 3 - 12 recursions, and see if it aborts properly.
ActionLoopTestCase::triggerActions in modules/simpletest/tests/actions.test
Create an infinite loop by causing a watchdog message to be set, which causes the actions to be triggered again, up to actions_max_stack times.
ActionsConfigurationTestCase::testActionConfiguration in modules/simpletest/tests/actions.test
Test the configuration of advanced actions through the administration interface.
actions_loop_test_action_info in modules/simpletest/tests/actions_loop_test.module
Implements hook_action_info().

... See full list

44 string references to 't'
CommonXssUnitTest::testFormatStringAndT in modules/simpletest/tests/common.test
Test t() and format_string() replacement functionality.
DatabaseBasicSyntaxTestCase::testLikeBackslash in modules/simpletest/tests/database_test.test
Test LIKE query containing a backslash.
DatabaseBasicSyntaxTestCase::testLikeEscape in modules/simpletest/tests/database_test.test
Test escaping of LIKE wildcards.
DatabaseDeleteTruncateTestCase::testSubselectDelete in modules/simpletest/tests/database_test.test
Confirm that we can use a subselect in a delete successfully.
DatabaseSelectCloneTest::testSelectConditionSubQueryCloning in modules/simpletest/tests/database_test.test
Test that subqueries as value within conditions are cloned properly.

... See full list


includes/bootstrap.inc, line 1720
Functions that need to be loaded on every Drupal request.


function t($string, array $args = array(), array $options = array()) {
  global $language;
  static $custom_strings;

  // Merge in default.
  if (empty($options['langcode'])) {
    $options['langcode'] = isset($language->language) ? $language->language : 'en';
  if (empty($options['context'])) {
    $options['context'] = '';

  // First, check for an array of customized strings. If present, use the array
  // *instead of* database lookups. This is a high performance way to provide a
  // handful of string replacements. See settings.php for examples.
  // Cache the $custom_strings variable to improve performance.
  if (!isset($custom_strings[$options['langcode']])) {
    $custom_strings[$options['langcode']] = variable_get('locale_custom_strings_' . $options['langcode'], array());
  // Custom strings work for English too, even if locale module is disabled.
  if (isset($custom_strings[$options['langcode']][$options['context']][$string])) {
    $string = $custom_strings[$options['langcode']][$options['context']][$string];
  // Translate with locale module if enabled.
  elseif ($options['langcode'] != 'en' && function_exists('locale')) {
    $string = locale($string, $options['context'], $options['langcode']);
  if (empty($args)) {
    return $string;
  else {
    return format_string($string, $args);


sreynen’s picture

Note: t() should not be used in hook_schema(). See: http://drupal.org/node/332123

redsd’s picture

Allthough it's described, I thoughed the drupal 6 had some good examples.

There are three styles of placeholders:

!variable, which indicates that the text should be inserted as-is. This is useful for inserting variables into things like e-mail.

    $message = t("If you don't want to receive such e-mails, you can change your settings at !url.", array('!url' => l(t('My account'), "user/$account->uid")));

@variable, which indicates that the text should be run through check_plain, to escape HTML characters. Use this for any output that's displayed within a Drupal page.

    $title = t("@name's blog", array('@name' => $account->name));

%variable, which indicates that the string should be HTML escaped and highlighted with theme_placeholder() which shows up by default as emphasized.

    $message = t('%name-from sent %name-to an e-mail.', array('%name-from' => $user->name, '%name-to' => $account->name));
songyy’s picture

Thanks I've been looking for info on this for long time. Nice to see it in your comments :)

dpi’s picture

Core, and Dynamic or static links and HTML in translatable strings documentation page prefers that inline links insert HTML directly into the translatable string.

You shouldn't construct link markup as t() variables with l() etc.

  $BAD_EXTERNAL_LINK = t('Look at Drupal documentation at !handbook.', array('!handbook' => ''. t('the Drupal Handbooks') .''));

  // Do this instead.
  $external_link = t('Look at Drupal documentation at the Drupal Handbooks.', array('@drupal-handbook' => 'http://drupal.org/handbooks'));

Extracted from http://drupal.org/node/322774

Web-Beest’s picture

Thanks! Very usefull!

aryashreep’s picture

Thanks! Very usefull!

seddonym’s picture

Because of t() also accepting a 'context' for string translations, the following doesn't work in D7:

$conf['locale_custom_strings_en'] = array(

Instead, you need to nest it one level deeper in an empty string (assuming no context was provided in the original call to t()):

$conf['locale_custom_strings_en'][''] = array(
songyy’s picture

Thanks I've been looking for info on this for long time. Nice to see it in your comments :)

yannickoo’s picture

Here is an example if you want to use a context for a translated string:

print t('Order', array(), array('context' => 'Verb'));

That means that the word 'order' is a verb so that nobody thinks that is the drupal commerce order.

cornel.eftimie’s picture

If the text displayed with the t() function doesn't appear in the translate interface try displaying the page containing it, in a language other than the default one. It worked for me.

hefox’s picture

Ditto, worked for me also.

jonathanpglick’s picture

If you want to get a string into the translate interface programmatically (without displaying the page containing it) you can call:

locale($string, '');

The empty string as the second argument is important!

sdsheridan’s picture

Actually, I think the second parameter should not necessarily be the empty string if you're trying to introduce a string into the translate interface with a particular context. That second parameter is the context, and you may indeed want to specify it.

rccprince’s picture

How to refresh translate strings in views template file?


penyaskito’s picture

t(NULL) returns an array with all the strings in the system. Not sure if a bug or a curiosity.

infinito’s picture

It's on purpose if you look at the function

jmcejuela’s picture

I'm creating a module that allows creating nodes and emails reading the info from external resources. Some of the information involved is dates, and I would like my module's users to format their dates as they want and write them in the node fields. Is there a standard way perhaps with t and placeholders to format dates?

josephcheek’s picture

Is there any problem with using newlines inside a single string to be translated? I know that HTML doesn't care, but does t() or any part of the drupal translation API? Is it ok to do

t('This is a long line of text and, as such, will be wrapped onto two lines
  in the source.  Is that ok?');

or must I instead do

t('This is a long line of text and, as such, will be wrapped onto two lines ' .
  'in the source.  Is that ok?');


PQ’s picture

Generally speaking, the house style seems to be to leave string definitions unbroken (on one line) in the source. The coding standards are slightly vague on this as I read them:

Lines containing longer function names, function/class definitions, variable declarations, etc are allowed to exceed 80 chars.

majorrobot’s picture

I discovered the hard way that, though you can provide a $langcode to t(), it will never translate *back* to the default language. For instance, if you want to know if a translated string equals a certain value in your default language (in this case, English),

t($string, array(), array('langcode' => 'en'));

will frustratingly always return your translated string instead of the default language string. Here is a function that wraps t() and helps get around this (note that it needs work — specifically incorporating caching):

function t2($string = "", $context = NULL, $langcode = '') {
  $t = $string;

  if ($string !== "") {
    if ($langcode == "en") {
      $sql = 'SELECT s.source 
        FROM {locales_source} s
        JOIN {locales_target} t
          ON s.lid = t.lid
        WHERE t.translation = :string';

      $results = db_query($sql, array(':string' => $string));
      foreach ($results as $row) {
        $t = $row->source;
    else {
      $t = t($string, $context, array('langcode' => $langcode));
  return $t;
petu’s picture

Thanks for the function! It works!
But the parameter $context should be array() not NULL.

The first string should be 'function t2($string = "", $context = array(), $langcode = '') {'

mamourou’s picture

Hello team,
I'm new on drupal system and i have a problem. When i keep to throw my drupal site with Filezilla i receive this error message :

Warning: require_once(/htdocs/includes/bootstrap.inc): failed to open stream: No such file or directory in /htdocs/index.php on line 19
Fatal error: require_once(): Failed opening required '/htdocs/includes/bootstrap.inc' (include_path='.:/usr/share/php') in /htdocs/index.php on line 19

Please help me

drusite’s picture

How to translate the word Menu ?
t('Menu') doesn't work in this case.

<?php if($menu_bar = render($page['menu_bar'])): ?>
		  <!-- MAIN NAV -->
		  <div id="menu-bar-wrapper" class="wrapper">
		    <div class="container <?php print $grid; ?>">
			  <div class="grid-inner clearfix">
			    <a title="Navigation Icon" href="javascript:void(0);" class="tb-main-menu-button responsive-menu-button">Menu</a>
			    <?php print $menu_bar; ?>