8.5.x bootstrap.inc t($string, array $args = [], array $options = [])
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.2.x bootstrap.inc t($string, array $args = array(), array $options = array())
8.3.x bootstrap.inc t($string, array $args = [], array $options = [])
8.4.x bootstrap.inc t($string, array $args = [], array $options = [])
8.6.x bootstrap.inc t($string, array $args = [], array $options = [])
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())

Translate strings to the page language or a given language.

Human-readable text that will be displayed somewhere within a page should be run through the t() function.


if (!$info || !$info['extension']) {
  form_set_error('picture_upload', t('The uploaded file was not an image.'));
$form['submit'] = array(
  '#type' => 'submit',
  '#value' => t('Log in'),

Any text within t() can be extracted by translators and changed into the equivalent text in their native language.

Special variables called "placeholders" are used to signal dynamic information in a string which should not be translated. Placeholders can also be used for text that may change from time to time (such as link paths) to be changed without requiring updates to translations.

For example:

$output = t('There are currently %members and %visitors online.', array(
  '%members' => format_plural($total_users, '1 user', '@count users'),
  '%visitors' => format_plural($guests->count, '1 guest', '@count guests'),

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' => url("user/{$account-&gt;<span class="php-function-or-constant property member-of-variable">uid</span>}", array(
    'absolute' => TRUE,
  • @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.
drupal_set_title($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 <em>emphasized</em>.
$message = t('%name-from sent %name-to an e-mail.', array(
  '%name-from' => $user->name,
  '%name-to' => $account->name,

When using t(), try to put entire sentences and strings in one t() call. This makes it easier for translators, as it provides context as to what each word refers to. HTML markup within translation strings is allowed, but should be avoided if possible. The exception are embedded links; link titles add a context for translators, so should be kept in the main string.

Here is an example of incorrect usage of t():

$output .= t('<p>Go to the @contact-page.</p>', array(
  '@contact-page' => l(t('contact page'), 'contact'),

Here is an example of t() used correctly:

$output .= '<p>' . t('Go to the <a href="@contact-page">contact page</a>.', array(
  '@contact-page' => url('contact'),
)) . '</p>';

Avoid escaping quotation marks wherever possible.


$output .= t('Don\'t click me.');


$output .= t("Don't click me.");

Because t() is designed for handling code-based strings, in almost all cases, the actual string and not a variable must be passed through t().

Extraction of translations is done based on the strings contained in t() calls. If a variable is passed through t(), the content of the variable cannot be extracted from the file for translation.


$message = 'An error occurred.';
drupal_set_message(t($message), 'error');
$output .= t($message);


$message = t('An error occurred.');
drupal_set_message($message, 'error');
$output .= $message;

The only case in which variables can be passed safely through t() is when code-based versions of the same strings will be passed through t() (or otherwise extracted) elsewhere.

In some cases, modules may include strings in code that can't use t() calls. For example, a module may use an external PHP application that produces strings that are loaded into variables in Drupal for output. In these cases, module authors may include a dummy file that passes the relevant strings through t(). This approach will allow the strings to be extracted.

Sample external (non-Drupal) code:

class Time {
  public $yesterday = 'Yesterday';
  public $today = 'Today';
  public $tomorrow = 'Tomorrow';


Sample dummy file.

// Dummy function included in example.potx.inc.
function example_potx() {
  $strings = array(

  // No return value needed, since this is a dummy function.

Having passed strings through t() in a dummy function, it is then okay to pass variables through t().

Correct (if a dummy file was used):

$time = new Time();
$output .= t($time->today);

However tempting it is, custom data from user input or other non-code sources should not be passed through t(). Doing so leads to the following problems and errors:

  • The t() system doesn't support updates to existing strings. When user data is updated, the next time it's passed through t() a new record is created instead of an update. The database bloats over time and any existing translations are orphaned with each update.
  • The t() system assumes any data it receives is in English. User data may be in another language, producing translation errors.
  • The "Built-in interface" text group in the locale system is used to produce translations for storage in .po files. When non-code strings are passed through t(), they are added to this text group, which is rendered inaccurate since it is a mix of actual interface strings and various user input strings of uncertain origin.


$item = item_load();
$output .= check_plain(t($item['title']));

Instead, translation of these data can be done through the locale system, either directly or through helper functions provided by contributed modules.

During installation, st() is used in place of t(). Code that may be called during installation or during normal operation should use the get_t() helper function.


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

$args: An associative array of replacements to make after translation. Incidences of any key in this array are replaced with the corresponding value. Based on the first character of the key, the value is escaped and/or themed:

  • !variable: inserted as is
  • @variable: escape plain text to HTML (check_plain)
  • %variable: escape text and theme as a placeholder for user-submitted content (check_plain + theme_placeholder)

$langcode: Optional language code to translate to a language other than what is used to display the page.

Return value

The translated string.

See also




586 calls to t()
aggregator-feed-source.tpl.php in modules/aggregator/aggregator-feed-source.tpl.php
aggregator-feed-source.tpl.php Default theme implementation to present the source of the feed.
aggregator-item.tpl.php in modules/aggregator/aggregator-item.tpl.php
aggregator-item.tpl.php Default theme implementation to format an individual feed item for display on the aggregator page.
aggregator-summary-items.tpl.php in modules/aggregator/aggregator-summary-items.tpl.php
aggregator-summary-items.tpl.php Default theme implementation to present feeds as list items.
aggregator_admin_remove_feed in modules/aggregator/aggregator.admin.inc
aggregator_admin_settings in modules/aggregator/aggregator.admin.inc
Form builder; Configure the aggregator system.

... See full list

14 string references to 't'
blogapi_mt_validate_terms in modules/blogapi/blogapi.module
Blogging API helper - find allowed taxonomy terms for a node type.
forum_term_load in modules/forum/forum.module
Fetch a forum term.
get_t in includes/bootstrap.inc
Return the name of the localisation function. Use in code that needs to run both during installation and normal operation.
system_region_list in modules/system/system.module
Get a list of available regions from a specified theme.
taxonomy_autocomplete in modules/taxonomy/taxonomy.pages.inc
Helper function for autocompletion

... See full list


includes/common.inc, line 962
Common functions that many Drupal modules will need to reference.


function t($string, $args = array(), $langcode = NULL) {
  global $language;
  static $custom_strings;
  $langcode = isset($langcode) ? $langcode : $language->language;

  // 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[$langcode])) {
    $custom_strings[$langcode] = variable_get('locale_custom_strings_' . $langcode, array());

  // Custom strings work for English too, even if locale module is disabled.
  if (isset($custom_strings[$langcode][$string])) {
    $string = $custom_strings[$langcode][$string];
  elseif (function_exists('locale') && $langcode != 'en') {
    $string = locale($string, $langcode);
  if (empty($args)) {
    return $string;
  else {

    // Transform arguments before inserting them.
    foreach ($args as $key => $value) {
      switch ($key[0]) {
        case '@':

          // Escaped only.
          $args[$key] = check_plain($value);
        case '%':

          // Escaped and placeholder.
          $args[$key] = theme('placeholder', $value);
        case '!':

          // Pass-through.
    return strtr($string, $args);


miro_dietiker’s picture

Note that there's an equivalent to t() for using translateable strings in JS called Drupal.t();

danielb’s picture

Here is something that wasn't obvious to me from reading the documentation here. While block tags around text like <p> and <div> are discouraged, it is acceptable to use inline HTML such as <strong> tags around words.
See http://drupal.org/node/322774

span’s picture

It should also be noted that the string is not added to the database until it has been displayed in a language that is not the default. It is not enough to only display the string in the default language to be able to translate it via 'Translate interface'.

lowfour’s picture

@ Span

You are the man. I was going crazy trying to make my templates ready for translation but couldn't find the print t('STRING') strings in "translate interface / search" despite flushing all caches and running cron. Very strange behavior indeed.

blue_waters’s picture

Yes - another big thank you here - since I was also wondering how to get the strings to appear in the translation table.

Nick_vh’s picture

"If you're visiting the Default language (mostly English) version of the site the translation table doesn't get populated... t() just output the passed string without accessing the DB. "
I couldn't understand the code that makes this possible but it is true so pay attention if you cannot find your translation when seeing the english site.

Somehow I missed to see all the comments above so now you are warned twice :-)

seddonym’s picture

I've written a method here for handling the deployment of string translations: