Localized and Multi-Lingual Content in Drupal 7

The way that Drupal manages translations has been evolving over several versions of Drupal. It has always been somewhat daunting to figure out how to set up a multilingual site in Drupal, and it requires a combination of core and contributed modules to make it work well. In Drupal 7 we have some great new features, but we also ended up with two different systems of managing content translation, so there are also lots of new questions and options. If you're new to Drupal's multilingual system, or new to Drupal 7, you'll have lots of questions about how to get this working well.

To make this whole process easier we'll cover the following in this article:

Understanding the difference between interface and content translation

Discuss the two alternative systems for content translation in Drupal 7 and how they differ

Walk through the installation and set up of a D7 multilingual site

Provide an extensive list of modules, articles, and resources that may be helpful

Interface Translation

There are two basic components to the translation system, the translation of the interface and the translation of content.

Translating the interface has to do with the translation of miscellaneous text strings used all over the site (like the label used on Submit buttons). These are elements that are the same on all sites no matter what actual content it contains. Because these strings are standardized, Drupal is able to create a system to provide everyone with translated values for all these elements in various languages. To take advantage of this you enable the core Locale module, which will allow you to grab translated text from the Drupal Localizer site and import them into your site. Then voila!, you will have French or German versions of the interface text on your site, without any need to translate them yourself.

For the developers in the room, the heart of the interface system is the strings that are passed through the t() function. You can see how many of these strings have been translated into various languages in the graph on the home page at Drupal Localizer site. That site serves as a central location used by translators from around the world to maintain interface translations for all Drupal projects, both core and contributed modules.

Content Translation

Once you have the interface translated, the real challenge is to find a good way to translate your content. No one else has the same content you have, there is no way you can download that automatically. To do this you need a place where you can store the translated version of the content (in as many languages as you need) and a system that will choose which content to display where.

This problem was solved in earlier versions of Drupal by creating a complete copy of each node that needs translation. So the French node would have all the French values of the content and the English node would have all the English values. Then they are organized together in translation sets, so Drupal knows which ones are the 'same' content.

This is the system used in older versions of Drupal, and it is still available in Drupal 7, if you enable the core Content Translation module.

Entity Translation

In Drupal 7, a new model for content translation was created. In this system each piece of content consists of a single node, but each field on the node can have multiple copies, in different languages, all attached to the same entity.

The API to get this system working went into core, but there was no time (and not enough agreement) to get a UI into core. So the Entity Translation module was created to provide a way for site administrators and translators to use the new field translation system. (In the illustration above, note that the title is only translatable if you use the Title module.)

The most confusing thing about the D7 translation system is that both these systems are available in D7. You can even use one system for one content type and the other for another content type. If you only want the D6-style translation set system, you would enable the core Content Translation module and not use the contributed Entity Translation module at all. If you only want the D7 per-field translation system, you would not enable the core Content Translation module and instead enable the contributed Entity Translation module.

The Pros and Cons

There are pros and cons of each system. The original system of creating translation sets was the easiest way to solve the problem before the new field system went into core, but it leaves you with multiple nodes that are really the 'same'. That can be a problem for SEO and is also a problem when combined with some contributed modules. For instance, if you have a node that describes an event and you want people to sign up for the event, you don't want them signing up separately for the English and French nodes, you want all the sign ups on the same node.

But if you have a single node with translated fields, it becomes harder to do things like have different menu entries or workflows for each language. The Content Translation Models Debate is a great screencast by Gabor Hojtsy that illustrates some of the pros and cons of each alternative. Note that many of the problems for each model are solved, at least to some extent, with contributed modules, which is one reason why it takes so many modules to make the system work.

If you don't know which model to use, or if you think they seem to be equally suited to meet your needs, you probably should opt for the newer model that allows you to have multiple field translations on a single node. There are still a few problems with this model for some use cases, but there are people working to solve those problems and make this system flexible enough to work everywhere.

Creating a Site Using Entity Translation

To illustrate how this works in Drupal 7, let's walk through how to set up a site that will translate content into several languages, using the per-field translation model. We'll create a clean D7 install, set up as an English speaking site, and then add multilingual capability to it.

Add Localization

Start by enabling Locale and Localization Update. That will give us two new options on the Administration Configuration screen.

First, go into the Language section and add whatever languages are desired, by clicking on the Add language link and selecting the language.

Then select the Detection and Selection tab. This is where you determine how Drupal will determine which language to display to the user. For most sites the url option will make the most sense. With this option Drupal will send the Spanish users to a path prefixed with 'es' and the French users to a path prefixed with 'fr'. You can select more than one option, and re-arrange them to indicate what order they will be tested.

The other option on the Administration Configuration screen, Translate Interface, contains tools to import, update, and manage the interface strings mentioned above.

You can see that you can tell what languages are installed, see the strings that are being translated and what the translations look like, and even update them from this screen. You won't need any of these right now, but this is where to go if you need to make changes or update these values in the future. The Update tab was added by the Localization Update module, and it makes it easy to see if you have the latest translations for all of your enabled modules.

Next go to the Content Type edit page and poke around in the vertical tabs at the bottom of the page, you will see there is now a new option to translate that content type.

If you select that option, it will add a new field on the nodes that you create, where you can select a language for that node.

Finally, go to the block administration page and add the Language Switcher block to the page. This will allow the user to choose the interface language they want to see.

At this point we have a site that can create nodes in various languages, but we can't translate one node into multiple languages. We have a site that has localization, but not translation.

Add Translation

To add translation to the site we need to turn on additional modules. Since we've decided to use the Entity Translation model (a single node with fields in multiple languages), we will not enable the core Content Translation module and instead enable the contributed Entity Translation module. Since we need the Title translated as well as other fields, we also need to enable the Title module.

Finally, we will want to translate not only the content of the fields, but also things like the field labels and descriptions. And if we have fields with lists of allowed values we want to be able to create translated versions of those lists. To translate those we need to enable the contributed Internationalization (i18n) package. That is actually a whole suite of modules that fill in some of the gaps left in the translation system. We don't yet need all of the modules in the package, but we want the core module and the Field Translation module (which translates field properties).

We will need to enable the Entity API module and the Variable modules as well, because some of our module depend on them.

After enabling these modules, we re-visit the content type administration page. When we edit each content type we now see a new option to enable Entity Translation for this content type.

On the Manage Fields screen for each content type we now see an option to replace the regular title with a field.

After making this change, the title will be an editable field, just like all the other fields. The title will also be displayed in the content like any other field, so you may want to go to the Manage Fields screen and hide it, since you will see the title at the top of the page already.

For each field that needs to be translated, click on the Field settings link and check the box to translate this field.

If there is already content in this field you will see a message noting that, but you can still change the option to translate the field. This should just serve as a reminder that the content in those fields is not yet translated.

The final step is to create or edit a page that has a language and we now see a new tab on the page in addition to the View and Edit tabs, a Translate tab. This tab takes us to a page that shows us each language we have enabled on the site where we can add a translated version of the content for that page. Note that this tab will only appear on nodes that have a language selected.

There are new options on the node edit page. In addition to the box to select a language, there is a way to flag translations as outdated.

Adding More Features

That is enough to get started with the Drupal 7 multilingual system. There are lots of other modules and features you can add to make the system better. The Internationalization (i18n) module includes additional modules to translate taxonomy terms or menu items or forums. And there are several other modules that provide additional functionality that could be useful. A number of them are listed below. Some are not totally ported to Drupal 7 yet and your mileage may vary, but you can explore all these options, depending on your needs.

Resources

Core Modules:

Locale: translate the user interface into different languages and create different date formats for each language.

Content Translation: translate content, where each language is in a separate entity and they are connected in translation sets.

Administration Modules:

None of these are required for a multi-lingual site to function correctly, but may be useful to make administration easier.

Localization Update, adds the same update capability for translations as Drupal has for modules, to make it easier to keep translations up to date using the Localize Drupal site:
http://drupal.org/project/l10n_update

Localization Client, helps you keep your translations up to date more easily with an on-page UI where you can fix the translations as you navigate the site:
http://drupal.org/project/l10n_client

Translation Overview, administration table that shows what content has been translated into what languages:
http://drupal.org/project/translation_overview

Translation Table, a table to make it easier to change the text for menus, variables, taxonomy, field names, etc:
http://drupal.org/project/translation_table

Admin Language, let the administrator see all administration pages in a chosen language, no matter what language the site uses:
http://drupal.org/project/admin_language

Install Profiles/Features:

Localized Drupal, an installation profile that automatically sets up Drupal site that is configured to use the multi-lingual system:
http://drupal.org/project/l10n_install

Links:

Extensive explanation of how the D7 translation system works by Gabor Hojtsy:
http://hojtsy.hu/multilingual-drupal7

The Content Translation Models Debate, a screencast that illustrates the evolution of how multi-lingual content was handled in core in Drupal 5, 6, and 7, and the issues that still need to be resolved in Drupal 8:
http://groups.drupal.org/node/165194

Drupal.org Translation Handbook page:
http://drupal.org/node/133977

An Overview of Field Translation by Randy Fay:
http://randyfay.com/node/88

The Localize site where all Drupal translations live:
http://localize.drupal.org/translate

Translation services:

And while we're on the subject of translation, a list of links to sites/services that help get content translated:

Translatable Regions, a Drupal module that integrates with the Google Translation API, there are discussions about how to proceed now that the Google Translation API is no longer free, it looks like it will use jQuery Translate:
http://drupal.org/project/translatableregions

Google Translation API, sadly the free service has been deprecated:
http://code.google.com/apis/language/translate/overview.html

jQuery Translate (Will switch to use Microsoft translation interface now that Google's is deprecated):
http://code.google.com/p/jquery-translate/