Multilingual Sites that Translate Well

Drupal's t() function allows translating texts from one language to others. In order to work right, you must create texts that translate well. We’ll show you frequent mistakes and how to correct them.

Localization 101

Once you've created a site, using the t() function, Drupal will scan the texts and send them to translation. The String translation mechanism allow replacing the texts in the original language with texts in other languages.

Translators cannot change anything else in the site or in the HTML. They only translate the texts that you give them.

Some of the things that translators cannot do:

  • Change the order in which texts appear
  • Merge or split texts
  • Translate texts that are not inside the t() function

Give your translators complete sentences

When translators get single words to translate, it's practically impossible to translate them correctly. They need to see full sentences in order to translate with meaning.

A common case is the login message:

You must be logged in to post a comment.

Too often, folks create this message using this code:

<?php print t('You must be') ?> <a href="<?php print url('user/login') ?>">
<?php print t('logged in ') ?></a> <?php print t('to post a comment.') ?>

This means that the translator now sees three strings to translate:

You must be
logged in
to post a comment.

Each of these strings makes little sense.

Did you know that the English word "be" has several meanings in Spanish?

Be can mean what you are (ser) or where you are (estar). Translators cannot tell which one you mean when they just see "you must be".

To fix this and create a sentence that translates well, we'll merge all these strings into a single sentence, as it's supposed to be in the first place.

We'll use placeholders to insert values from other functions into the sentence.

<?php print t('You must be <a !link>logged in</a> to post a comment' ),
 array('!link' => 'href="' . url('user/login') . '"') ) ?>

Now, it's crystal clear. The translator sees one sentence, from start to finish. If needed, the translator can swap between parts of the sentence and write it correctly in any language.

Beyond complete sentences

When we create multilingual sites, we need to remember that translation is not everything. Localization means adapting the site to a different language, country and conventions.

We need to create interface strings that allow adjusting things like:

  • Number formats
  • Date formats
  • Units
  • Phone numbers (adding country codes)
  • Addresses (adding the country)
  • and many others...

The first and most important step is understanding. Once we understand that localization only begins with adding t() functions, we'll create much better websites that read natural in any language.

Comments

Thanks for such an

Thanks for such an informative article.

Drupal styleguide

Actually the Drupal style suggests this:

<?php print t('You must be logged in to post a comment' ),
array('@url' => url('user/login'))); ?>

1. Note the first difference is that href="" is included in the string. The reason is that the string itself will be valid HTML this way. Translators can be sure that no other attribute (such as title=...) will be included in that section of replacement, it is purely the URL.

2. Note that I've used @url instead of !link. The reason for this is security. While url() might not generate XSS attackable links in itself (although it is possible to inject query string fragments in circumstances), external links might appear at several places. Getting to the habit of using @url placeholders makes your output be escaped for HTML based attacks. It's important for security.

Thanks for the clarifications

You're absolutely right. We'll use these conventions when we create a guide about how to write multilingual themes.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options