(For more resources on Drupal, see here.)
Getting up and running
Before we get started, we obviously need a Drupal 7 website to work on. This section gives you two options, namely, roll your own or install the demo.
Using your own site
You can use your own Drupal 7 site. It can be an existing site or one you create from scratch. If you are creating a brand new site and weren't planning on using a particular installation profile, you can get a head start by using the Localized Drupal Distribution install profile at drupal.org/project/l10n_install.
It is probably obvious, but it's best to run the site on a development machine and not in a production environment. Once all the basic Drupal core modules are configured, you will also want to set up the following additional modules to get the most out of the exercises:
- Panels: A tool for creating pages with custom layouts
- Path auto: Settings for creating path aliases automatically
- Views: A tool for creating custom pages and blocks
Using the demo site
If you'd prefer a jump-start, a full demo website can be created using a special install profile.
Instructions for downloading and installing the demo website are included on the Drupal project page available at drupal.org/project/multilingual_book_demo. The demo site contains additional modules including the modules listed previously as well as the following:
- Administration Menu: Toolbar for quick access to the site configuration
- Views Bulk Operations: Extra functionality for Views forms
- Views Slideshow: Slideshows of content coming from Views
These modules provide us with a starting point. As more modules are needed for particular exercises, they will be listed so you can add them.
Roles, users, and permissions
Although you might already have multiple users on your test site, for simplicity it will be assumed that you are logged in as the super admin (user ID 1).
Working with languages
If we want a multilingual site, the logical first step is to add more languages! In this section, we will add languages to our site, configure how our languages are detected, and set up ways to go between these languages.
Adding languages with the Locale module
Drupal has language support built into the core, but it's not fully turned on by default. If you go to your site right now and navigate to Configuration | Regional and language, you will see the Regional settings and Date and time comfit page s for configuring default country, time zone, and date/time formats:
- To get our languages hooked in, let's enable the core module, Locale. Now go back to Configuration | Regional and language to see more options:
- Click on Languages and you'll see we only have English in our list so far:
- Now let's add a language by clicking on the Add language link. You can add a predefined language such as German or you can create a custom language.
- For our purposes, we will work with predefined languages. So choose a language and click on the Add language button.
Drupal will then redirect you to the main language admin page and your new language will be added to the list.
- Now you can simply repeat the process for each language. In my case, I've added three new languages, namely, Arabic, German, and Polish:
The overview table shows the language's name (English and native), its code, and its directionality. The language's direction can be Left to right (LTR) or Right to left (RTL), with most languages using the former. 'Right to left' just means that you start at the right side of the page and move towards the left side when you are writing. RTL languages include Arabic, Hebrew, and Syriac, which are written in their own alphabets.
You can choose which languages to enable, order them, and set the site default. Links are provided to edit and delete each language. English only has an edit link since it is the system language and cannot be deleted, but English can be disabled if you use a non-English default. If we edit a language, we can modify all the information from the overview table except for the language's code since we need that as a consistent reference string.
Do not change the default language once you have started translating or translations might break.
Install String Translation from the Internationalization package (drupal.org/project/i18n), go to Configuration | Regional and language | Multilingual settings | Strings, select the Source language, and click on Save configuration. Do not change this setting once it's configured.
We have our languages, so now what? If you click around your site, nothing looks different. That's because we are looking at the English version of the site and we haven't told Drupal how we want to deal with the other languages. We'll do that now.
Navigate to Configuration | Regional and language | Languages | Detection and selection and you'll see we have a number of choices available to us:
The Default detection method is enabled for us, but we can also enable the URL, Session, User, and Browser options. If you want a cookie-based option, check out the Language Cookie and Locale Cookie modules. Let's go over the core options in more detail.
If you enable this method, users can navigate to URLs such as example.com/de/ news or example.com/deutsch/news (when using the path prefix option) and example.de/news, deutschexample.com/news, or deutsch.example.com/news (when using the domain option). Configuring domains requires web server changes, but using path prefixes does not. This is a common configuration for multilingual sites, and one we'll use shortly.
The language's path prefix can be changed when editing the language. If you want to use path-prefixed URLs, then you should decide on your path prefixes before translating content as changing path prefixes might break links (unless you set up proper redirects). If desired, you can choose one language that does not have any path prefix. This is common for the site's default language. For example, if German is the default language and no path prefix is used, the news page would be accessed as example.com/news whereas other languages would be accessed using a path prefix (for example, example.com/en/news).
The Session option is available if you want to store a user's language preference inside their user session. It was actually proposed by some Drupal community members that this method be removed from the set of choices as it caused a number of issues in other code.
One reason you may not want to use this option is due to the possible inconsistency between the content and the URL language. For example, you could enable both URL and Session methods and order them so that the Session method is first. If a user is at example.com/de and if the session is set to French, then the user will see French content even though the URL corresponds with German. My advice is to just skip this one, or, if you need it, at least make sure that it's ordered below the URL option.
Once the Locale module is enabled, users can specify their preferred language when they edit their account profile. If you enable the User method in the detection settings, the user's profile language will be checked when deciding what language to display. Note that the user profile language defaults to the site's default language.
Users can configure their browsers to specify which languages they prefer. If the Browser method is enabled, Drupal will check the browser's request to find out the language setting and use it for the language choice. This option may or may not be useful depending on your site audience.
The default site language is configured on the Configuration | Regional and language | Languages settings page, and is used for the Default detection method. Although you can't disable this method, you can reorder it if you choose. But, it makes the most sense to keep it at the bottom of the list to use it as the fallback language.
Detection method order
It is important to note that the detection method order is critical to how detection works. If you were to drag the Default method to the top of the list, then none of the other methods would be used and the site would only use the default language. Similarly, if you allow a user profile language and drag User to top of the list, then the URL method would not matter even if it's enabled. Also, if URL detection is ordered below Session, User, and Browser options, the user might see a UI language that does not match up with the URL language, which could be confusing.
Make sure to think carefully about the order of these settings. If you use the URL method, it's likely you will want it first. The Default method should be last. The other detection method positions depend on your preference.
When using path-prefixed URLs, if one language does not have a prefix, then detection for that language will work differently. For example, if the URL method is first, then no other detection methods will trigger for any URLs with no path prefix such as example.com/news or example.com/about-us.
For our purposes, let's stick with URL detection and use the path-prefix option as this is the easiest to configure (it doesn't require extra domains). This choice will keep our URLs in sync with our interface language, which is also user and SEO-friendly.
- Check Enabled for the URL method and press the Save settings button.
- Now click on Configure for that method and you'll see options for Path prefix and Domain. We'll use the default option, that is Path prefix (for example, example.com/de).
Don't panic on the next step. You won't see anything different in the UI until we finish our interface translation process later in the article.
- Now change the URL in your browser to include the path prefix for one of your languages. In my case, I'll try German and go to example.com/de. You should be able to use the path prefixes for each of your configured languages.
Switching between languages
Most likely you don't want your users to have to manually type in a different URL to switch between languages. Drupal core provides a language switcher block that you can put somewhere convenient for your users.
To use the block, navigate to Structure | Blocks, find the Language switcher (User interface text) block, position it where you'd like, and save your block settings. The order of the languages in the block is based on the order configured at Configuration | Regional and language | Languages. Once enabled, the language switcher block looks like the following screenshot:
You can now easily switch between your site languages, and the language chosen is highlighted. The UI won't look different when switching until we finish the next section. Two alternatives to the core language switcher block are provided by the Language Switcher and Language Switcher Drop-down modules. Also, if you want country flag icons added next to each language, you can install the Language Icons module.
(For more resources on Drupal, see here.)
Interface and string translations
Now that we have our languages configured and can switch between them, we want to start viewing text in these languages. For my site, I chose Arabic, German, and Polish. By going to http://localize.drupal.org, you can see that these three languages are pretty well supported in Drupal because many of the core UI strings have been translated already.
Take a look to see what progress has been made for your languages. If you want to use a language that hasn't been fully translated, you can always help with the translations yourself and contribute them back to the community. That's what Drupal is all about!
In this section, we'll learn how to translate the UI using the manual process and then by leveraging the Localization Update module. After our interface is in sync with the contributed translations, we will translate new strings into our languages and change existing translations that aren't to our liking. Finally, we'll find out how to send these new translations back to localize.drupal.org so that others can benefit from our hard work.
Translating the interface
For Drupal to know how to translate each interface string, it needs the mapping of the English strings to their translated counterparts. This is handled by using GNU gettext .po files, where po stands for portable object. A .po file looks like the following:
msgid "Enable developer modules"
msgstr "Entwicklermodule aktivieren"
The msgid is the English string and the msgstr is the translated version in the target language. The previous example is for a German translation and is in a file called de.po (remember de is the language code for German).
So, what we need to do is grab .po files for our site so that Drupal can start translating:
- Go to localize.drupal.org and use the Quick navigation to find your language. You will end up on the downloads page for that language where the available translation files are listed. Since version numbers change regularly, grab the latest 7.x version:
- Click on the Download link for Drupal core (7.x version) and save your file somewhere handy.
- Repeat for each language and then navigate to Configuration | Regional and language | Translate interface.
- Now click on the Import tab to upload the .po files which you have saved. Just import each one separately and assign the correct language when importing:
With the .po files imported, Drupal now knows how to translate many of the strings in the UI. The overview at Configuration | Regional and language | Translate interface shows the translation progress for the site's enabled languages.
Now if I look at the login form with the German interface, the text strings are in German. It's time to see for yourself! Switch between your languages to see the transformation.
If you want to have a different interface language for your administration pages, check out the Administration Language module.
Automatic translation updates
Ok, let's be honest. That was a bit tedious. What if I want to add more languages? What about all my contributed modules that need translation. I, for one, don't want to import each and every .po file for all my modules in all my languages! Fortunately, we don't have to because the Localization Update module comes to our rescue:
- Go ahead and install the Localization Update module (drupal.org/project/l10n_update) and then navigate back to the Configuration | Regional and language | Translate interface page.
- We now have an Update tab! Click on the tab and then wait for a few seconds (with bated breath).
- Once the Update page loads, you'll see the translation status for your website because the Localization Update module got all that information from localize.drupal.org. Cool!
The rest of our translations can be pulled over at the touch of a button!
- Click on Update translations and wait for a few minutes while Localization Update does all the hard work for you.
When the update is completed, all your translation status information will change accordingly.
Some projects might not have translations and translations are only made available for non-development releases, for example, 7.x-1.0 and not 7.x-1.0-dev.
To fully configure Localization Update, check out the config page at Configuration | Regional and language | Languages | Translation updates. For example, you can have the module update your site automatically on a daily or weekly schedule. Awesome!
Adding and fixing interface translations
Thanks to the Drupal community, we already have quite a bit of our interface translated. As more translations are contributed to localize.drupal.org, we can get these updates easily using the Localization Update module. What about strings that haven't been translated yet? Well, how about translating those ourselves?
- Let's start by doing this manually at the Configuration | Regional and language | Translate interface | Translate page. There is a string translation form provided where we can search for untranslated text in our site. If you restrict the search to untranslated strings in English, the search results will show all interface strings that need translation.
- If you know what text you want to translate, then type some of the text into the String contains box and click on the Filter button. Note that the search text is case sensitive. In my case, I have the Meta Tags module installed, so I can search for Add a meta tag. If you don't have Meta Tags installed, try a different text string like Add or Configure or help.
- To translate one of the strings, click on the edit link and fill out the translation form. Since I don't speak any of my new site languages, I will use Google Translate (translate.google.com) to get the text. This is definitely not recommended for a real site but will suffice for our demo.
If you search again for your text in the translated strings, you will see that it is marked as translated for the languages where you provided the text.
So now you probably understand how you would change an existing translation. Simply find the text you want to modify, click on the edit link and change the strings as desired. This is a straightforward process, but navigating through the long list of strings on the Translate page is cumbersome. Also, we may only want to worry about text that we see directly on our site and translate as needed. To make this process easier, we will need another handy module, that is Localization Client (drupal.org/project/l10n_client).
- Install the Localization Client module and flush your cache.
- Now if you switch to another language, you will see a new toolbar at the bottom of the page.
- Click on TRANSLATE TEXT on the bottom right and a useful form opens.
The actual link text depends on the translation available for TRANSLATE TEXT in the language you are working with.The left side of the form shows all the text accessible from the current page. If the text is highlighted in green, there is a translation available and the translated text is shown. If there is no translation, then the text is in its source language, ready for you to translate.
- Click on the text and it will show up in the center column (marked QUELLE in the previous screenshot because "quelle" means "source" in German).
- Then put the translated text into the box on the right and click on the Save translation button. If you want to use the source string as a template, click on the Copy source button first and then make your changes.
The actual button text depends on the translations available for Save translation and Copy source in the language you are working with.
It is important to note that you might encounter strings such as the following:
Use the @vocab_name terms of the page being shown.
Take notice of the special use of the @ symbol, which indicates a string placeholder. For this example, @vocab_name is a placeholder that should remain unaltered because it will be filled in dynamically by the system. String placeholders can start with @, !, or %. The following is an example using all three:
Date & time (!date %time) can be changed on the
<a href="@url">regional settings configuration page</a>.
Be careful to preserve these placeholders when you perform translations. The previous example in German might look similar to the following:
Datum & Uhrzeit (!date %time) finden Sie auf der
<a href="@url">regionalen Einstellungen Konfiguration
Seite geändert werden</a>.
Contributing translations back to the community
Now you know how to add and change translated UI text on your site. If you want to contribute your translations to the Drupal community, it's easy to do. Please do this if your translations are accurate! It benefits everyone using that language:
- If you are willing to share your translations, install the Localization Client module and enable the sharing option at the Configuration | Regional and language | Languages | Sharing page:
- Next, figure out which roles will be translating content. If there will be more than one translator, you'll probably want to add a dedicated translator role.
- Update your permissions so the appropriate roles have the Submit translations to localization server permission enabled.
- Flush your cache and switch to a user with this role.
- After you have logged in as a user who can share translations, edit the user's profile page.
- If you scroll down the page, you will have a new Localization Client section.
- Follow the instructions for getting Your Localization Server API key.
Create a key on a real site for real translations and not for testing.
- Save your key and translate away! Your translations are very welcome. You can even update your drupal.org profile to show off your new contributions:
Translating English strings
One thing that you might want to do is change some of your English interface strings in some way. For example, maybe you want the lofty word "Taxonomy" changed to "Categories" as well as any related text.
You can find all the strings with "Taxonomy" in them by using the Translate interface form at Configuration | Regional and language | Translation interface | Translate. Make sure to search for both uppercase and lowercase strings.
Once you have the strings to change, you need a way to change them since this unfortunately can't be done out-of-the-box for English strings. I'll cover three options, namely modifying the settings.php file, using the String Overrides module, and creating a custom English language.
Flush your caches after trying any of these methods so the new text shows up.
Modifying the settings.php file
If you have a small number of strings to modify, then a quick way to change the strings is to put them in an array in your settings.php file as follows:
$conf['locale_custom_strings_en'][''] = array(
'Taxonomy' => 'Categories',
'Taxonomy term' => 'Category term',
Using the String Overrides module
Another option when working with a minimal number of strings is to use the String Overrides module. Just install the module (drupal.org/project/stringoverrides) and navigate to the config page at Configuration | Regional and language | String overrides. Then fill in the original text on the left and the replacement text on the right and click on Save configuration. Super easy!
Creating a custom English language
If you plan on changing a lot of English strings, you can create a custom English language to replace your English language. If English is your default language, you can make the custom English language your default instead and then disable English. Then, if you are using the Localization Client or the Translate Interface page, you will be able to modify any of the English interface strings easily for your custom English language.
One problem with this approach is that it is not recommended that you change your default language once you have started translating content. Thus, a custom English language should only be added at the beginning of a project or, at least, before the localization process has begun or else the results might be bad.
For example, if you already have content in English and then create a new custom English, you'll end up with some nodes with the original English language code and some nodes with the new custom English language code (unless, of course, you go back and update all the old English content). Tread carefully or things can get confusing.
Reusing custom translated strings
If you want to reuse your translated strings for other websites, you can export the strings at Configuration | Regional and language | Translate interface | Export. Just choose the type of strings to export and click on the Export button and you'll get a .po file to save. Then you can import that .po file into your other Drupal websites via the Configuration | Regional and language | Translate interface | Import page. Neat!
After we created our test website, we worked with languages. We added several new languages and then configured the detection settings to handle different URLs per language based on the language's path prefix. Then, we added a handy block for switching between each language with ease.
Once the languages were in place, we moved on to Drupal interface translation. We got translation files directly from localize.drupal.org and imported them into our site. To make the job easier, we installed the Localization Update module to get the translation files for us automatically. We then learned that, unfortunately, not all the UI text has been translated. So we added our own string translations that can be shared back with the community. This process was simplified with the Localization Client module. For the last part of the UI translation section, we learned different methods for translating English strings and how to export our string translations for use on other Drupal websites.
- Drupal Theming [article]
- Translations in Drupal 6 [article]
- Building an Admin Interface in Drupal 7 Module Development [article]