Internationalization, also referred as i18n comes with its own set of challenges. It may seem relatively easy to dive into i18n modules and spin up a translation ready instance of D7. But let’s address a few caveats beforehand:
- Translation at content level (using i18n Module)
- Translation at code level, strings/variables with PO (Portable Object) files
- Translation for Menu items
- Translation for URL Paths (Path aliases or URL aliases)
- Translation for Taxonomies
- Translation for Blocks and Views
- Translation for Date and Time
By enabling community i18n module along with a couple of other core translation modules like Content translation and Locale you can get basic setup up and running for translations. As seen below it’s translation ready with Language Neutral (default)
Required Modules Installation
We just got a very basic translation ready setup, on the next step lets install some extended modules to make it fully translation ready. Install and activate these required modules (remember to get only stable releases):
- Internationalization (i18n)
- Localization update (l10n_update)
- Token (token)
- Chaos Tools (ctools)
- Views (views)
- Internationalization Views (i18nviews)
- Pathauto (pathauto)
- Transliteration (transliteration)
At the installation screen you can see that translation modules for Content, Block, Variable, Field, Path, Menu and Mail are all available, activate them accordingly.
Additionally you can also install Admin Language module to see translations for D7 admin, it’s not required but might come in handy.
Configuration and Setup
Navigate to your Regional and language settings in D7 admin. Here is where we start with adding a new Language. Date & Time settings are often overlooked but they should be customized to active language format. At the Regional and language -> Language screen we’ll see:
Let’s kickoff by adding a new Dutch locale for easy transliteration. Do note that languages like Russian, Greek, Japanese and Thai take Unicode characters and have to be translated to US-ASCII which works most of the time with average accuracy. Now it will show two languages and we can start enabling multilingual feature for content types.
By default D7 will not show any locale options during content creation or editing. This feature has to be enabled for each content type as below:
Once enabled you’ll have translation ready content available while creating content or editing an existing one. More complex part is how these translations will play within your site i.e. URL paths or aliases. We’ll take a deep dive into that later but let’s first discover this new feature as seen below when you create new content:
Now you’ll be able to see a language selection for content creation or editing. Evidently Language Neutral or English is set as default language so anything that gets published will be in default locale, unless otherwise changed. So let’s go forward and create an article that’s in Dutch locale.
One more step before it’s fully functional, turning on the URL translation. To make this as formal and basic we’ll go ahead with default URL structure that is offered out of the box. Although there could be more complex URL structures like:
- http://example.com/nl/content/eerste-hello-world-artikel (Default)
- http://nl.example.com/content/eerste-hello-world-artikel (Customized)
If you follow the Default URL structure it’s fairly easy to implement, but with customized URL structure there’s more skilled effort required to make it work. To make this URL structure work follow one last step:
At the Regional and language settings enable all the options to pick up the best available language alternative based on a user’s browser language preference, session settings or OS language settings. The OS language settings might not work but you can be sure that browser language will be picked up correctly.
Now that these settings are in effect you can be sure you’re almost there. So let’s create a new article in Dutch language:
Looks good so far but what about D7 module translations or translations that are suppose to be there but missing in admin. Most of these are extensively covered in D7 module development policies so you’ll be able to find translations for modules as well. To see overall translation summary you can just go to your Regional and language -> Translate Interface setting.
If there are missing translations just click on Update translations button at the bottom to download translation files (.PO files) for modules.
Translations can happen at content, block, menu, and views level. To piece this together let’s go ahead with menu translations as an example. By default menus are rendered in Language neutral (default) but when you move to a different language it should also change. Let’s move back to Strings tab and have those menu translations in effect as below:
This makes sure all the menu items are accounted for translation, now move back to Structure -> Menus to apply translations for Dutch locale. This step is known to only work from Menus.
While on that page you can click on translate link for any menu item that needs to be translated. We’ll test this out by clicking on In the News -> translate and add translation like below:
After adding your translation it should be visible on the next screen with two items, since we have only two locales configured.
Once translated these menu items will take effect whenever you browse a different locale URL or switch to another locale. To demonstrate this we added a default D7 block for Language switcher. What you’ll see next is menu links with default locale:
The highlight here is only In the News menu item, since that was the only one translated. Now let’s switch locale to Netherlands from top. This will eventually result in locale switch and consequently all the translated content will show up as seen below.
Internationalization requires vast implementation in Drupal 7 but maybe this is simplified to a great extent in Drupal 8. To cover all the aspects within this insight post might not be sufficient. Missing ingredients like translation for Blocks, Views, Strings and Variables cannot be covered or compressed.
Forming more advanced personalization like dynamic URL redirection, content, blocks and views based on Geo Location or a specific criteria is out of scope. More or less it deviates into personalization than translation, and so this is just a headstart on building multilingual sites with Drupal 7.