Drupal makes it easy to develop translatable interfaces by offering a few simple functions for writing a module's interface text, and then pushing the rest of the work onto the shoulders of a translator. Additionally, to simplify code patterns for developers, strings in certain locations are translated without the need to wrap them in translation functions. Let's discuss the basics of how Drupal translates the interface before diving into the details.
Introduction to interface translation in Drupal
A basic rule is that Drupal assumes that you write modules and themes in English. While technically there is nothing that prevents you from writing a module in Turkish or Chinese, the assumption of English as a default language creates a common ground both for translation and for sharing with the community. All modules and themes are translated from English to other languages.
Drupal finds strings to translate via functions, or "strategic placement" of strings. The most well known function for interface translation is
t(). (Indeed, it is Drupal's most-used function.) If, for example, you see the following in module or theme source code, then you have encountered a string made available for translation.
t('Click the button to go forward');
Important: do not localize user-provided content. The localization API is only for fixed strings in code. t() should never be called e.g. on a variable value that may contain user input.
You should try to make strings for translation full sentences or phrases when possible, and never begin or end with a blank space. Instead of breaking up strings or embedding variables in the middle, use placeholders. Strings that may have several meanings in English can take a context attribute.
Short introduction to the translator's view of your module or theme
There are several ways translators find out about your translatable strings. The strings identifiable via the translation functions and found in well-known places are automatically extracted for translation by the Drupal Localization Server. Translation teams can then find and translate these strings.
However please think of your translator fellows when you include new strings in your latest release. Translators now have to face 500,000+ strings on l.d.o, which sometimes seems an overwhelming challenge to manage. Especially in the light that a certain amount of those half-million strings are redundant duplicates of each other, due to developers' inconsistent manner. Smaller Translation Teams also consists of volunteers like you, using their limited freetime to introduce Drupal to new non-English user base. Developers can easily help Translators, if they perform a quick search on localize.drupal.org looking up any recyclable strings every time, when their new code changes.
Drupal itself also collects untranslated strings into the database as it finds them, and tools such as the built-in locale module and the Localization client can be used to translate on the web interface from web page to web page, as you go. Drupal can also export Gettext POT and PO files, and import PO files, making it possible to share translations with others.
Finally, the Localization server and Localization client can be used by teams to collaborate on translation projects. This tool uses the Translation template extractor as a background process to parse multiple modules.
In a theme's template (*.tpl.php file), if you want the string to appear directly, don't forget PHP "print" command, like this:
<p><?php print t('Reindeer herd') ?></p>
Then, before being able to translate it, you may need to rebuild the theme registry (Configuration → Performance, then click on "Clear all caches") and, for each translatable string, to visit a non-English page were the translated string will appear (this will force the translation function to collect the translatable string). Only then can you translate your string. The translatable strings from the theme template will appear in the "User interface" group of strings.
Get the cheat sheet!
Tips and tricks, common pitfalls, relevant functions, important parameters, and placeholder definitions are documented in the Drupal 6 translations cheat sheet (72KB PDF) created by Gábor Hojtsy in November 2007. Although the explanations here provide the necessary context to understand the cheat sheet, it is an invaluable reference for while coding.