Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.611.2.20 diff -u -p -r1.611.2.20 common.inc --- includes/common.inc 9 Jul 2008 19:34:30 -0000 1.611.2.20 +++ includes/common.inc 23 Dec 2008 23:52:47 -0000 @@ -642,8 +642,8 @@ function locale_initialize() { /** * Translate strings to the current locale. * - * All human-readable text that will be displayed somewhere within a page should be - * run through the t() function. + * Human-readable text that will be displayed somewhere within a page should + * be run through the t() function. * * Examples: * @code @@ -679,27 +679,27 @@ function locale_initialize() { * $message[] = t("If you don't want to receive such e-mails, you can change your settings at !url.", array('!url' => url("user/$account->uid", NULL, NULL, TRUE))); * @endcode * - * - @variable, which indicates that the text should be run through check_plain, - * to strip out HTML characters. Use this for any output that's displayed within - * a Drupal page. + * - @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. * @code * drupal_set_title($title = t("@name's blog", array('@name' => $account->name))); * @endcode * - * - %variable, which indicates that the string should be highlighted with - * theme_placeholder() which shows up by default as emphasized. + * - %variable, which indicates that the string should be HTML escaped and + * highlighted with theme_placeholder() which shows up by default as + * emphasized. * @code - * watchdog('mail', t('%name-from sent %name-to an e-mail.', array('%name-from' => $user->name, '%name-to' => $account->name))); + * $message = t('%name-from sent %name-to an e-mail.', array('%name-from' => $user->name, '%name-to' => $account->name)); * @endcode * * 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 is embedded links; link - * titles add additional context for translators so should be kept in the main - * string. + * 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 an incorrect use if t(): + * Here is an example of incorrect usage of t(): * @code * $output .= t('

Go to the @contact-page.

', array('@contact-page' => l(t('contact page'), 'contact'))); * @endcode @@ -709,7 +709,7 @@ function locale_initialize() { * $output .= '

'. t('Go to the contact page.', array('@contact-page' => url('contact'))) .'

'; * @endcode * - * Also avoid escaping quotation marks wherever possible. + * Avoid escaping quotation marks wherever possible. * * Incorrect: * @code @@ -721,6 +721,101 @@ function locale_initialize() { * $output .= t("Don't click me."); * @endcode * + * 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. + * + * Incorrect: + * @code + * $message = 'An error occurred.'; + * drupal_set_message(t($message), 'error'); + * $output .= t($message); + * @endcode + * + * Correct: + * @code + * $message = t('An error occurred.'); + * drupal_set_message($message, 'error'); + * $output .= $message; + * @endcode + * + * 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: + * @code + * class Time { + * public $yesterday = 'Yesterday'; + * public $today = 'Today'; + * public $tomorrow = 'Tomorrow'; + * } + * @endcode + * + * Sample dummy file. + * @code + * // Dummy function included in example.potx.inc. + * function example_potx() { + * $strings = array( + * t('Yesterday'), + * t('Today'), + * t('Tomorrow'), + * ); + * // No return value needed, since this is a dummy function. + * } + * @endcode + * + * 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): + * @code + * $time = new Time(); + * $output .= t($time->today); + * @endcode + * + * 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. + * + * Incorrect: + * @code + * $item = item_load(); + * $output .= check_plain(t($item['title'])); + * @endcode + * + * Instead, translation of these data can be done through the locale system, + * either directly or through helper functions provided by contributed + * modules. + * @see hook_locale() + * + * 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. + * @see st() + * @see get_t() + * * @param $string * A string containing the English string to translate. * @param $args