How To Localize WordPress Themes
If you are a WordPress theme developer or designer and you wish to localize your themes with your local language, this is a post not to be missed.
One of the amazing features about WordPress is the ability to display in all languages using GNU gettext localization framework. Theme developers can provide a localisation template file and allow users to translate their themes easily using software like PoEdit.
In this tutorial, we will look into how to create a POT localisation template file for your WordPress theme.
Here’s the shortcuts to get your themes localized
- Strings translation
- Enabling localisation
- Applying the function
- Creating the POT file
- PO & MO translation
- Helpful links
1. Translating strings, one at a time
WordPress uses gettext framework that provides message-level translation, that is, every string is translated individually. There are 2 WordPress functions that allows you to translate strings.
As a developer, you need to apply the function to all strings that you want to translate:
- __() returns the translated string.
<?php // assigning an untranslated string to $normal $normal = 'Featured Posts: '; // Example 1 , assigning a translated string to $translated $translated = __('Featured Posts: '); // Example 2 , assigning a translated string to $translated, skip translating the colon $translated = __('Featured Posts') . ': '; ?>
- _e() output the translated string
<?php // output an untranslated string echo 'Featured Posts: '; // this will output the translated string _e('Featured Posts: '); ?>
Note:
If no translation is provided for that string, the original string will be returned.
Difficult cases
Sometimes you might need to translate a string which has variables inside.
<?php $author = get_the_author(); // untranslated string $string = 'This blogpost is written by ' . $author; // translated example 1 $translated = __('This blogpost is written by ') . $author; // translated example 2 (BETTER) $translated = sprintf(__('This blogpost is posted by %s'), $author); ?>
Is example 1 a good translation?
It is not. This simply because not all languages works like english, there might be a language that works in another way round (for instance, mentioning the author name first, before saying “This blog post is posted by”)
Example 2 is better.
Example 2 is the correct way to translate this string. We are using a PHP function called sprintf()) that returns formatted strings. %s refers to a string literal, it’ll be replaced by the function’s next parameter, in this case: $author. Using this approach, the translator can decide where the author name should appear in the sentence.
Even more variables?
If the string have even more variables:
<?php $author = get_the_author(); $time = get_the_time(); // untranslated string $string = 'This blogpost is written by ' . $author . ' at ' . $time; // translated string $translated = sprintf(__('This blogpost is written by %s at %s'), $author, $time); ?>
The first %s will be replaced by the content of $author, the second %s will be replaced by the content of $time.
Note:
sprintf() returns the formatted string while printf() output the formatted string.
For more information on how to use the functions, please refer to the documentation.
2. Making your theme supports localisation feature
The localization feature is not enabled by default. Therefore, after applying __() and _e() to all your strings, now it’s time to make your theme supports this localization feature using load_theme_textdomain(). Add these lines to your theme’s functions.php :
<?php function mytheme_localisation() { load_theme_textdomain('yourthemename', get_template_directory() . '/languages'); } mytheme_localisation(); ?>
Of course, replace “yourthemename” with the $domain that you want, we recommend it to be your theme’s name.
Explanation for load_theme_textdomain($path , $domain)
- The first parameter $domain refers to an unique identifier for retrieving translated strings. In this case, our theme name will be the most suitable unique identifier.
- The second parameter $path sets the path to look for po/mo file. If undefined, the theme root folder will be the default path. In the example above, WordPress will look for po/mo files inside /theme-folder/languages/ folder.
3. Applying the function for all theme files
Next, add this lines to the very top of all PHP files in the theme.
<?php mytheme_localisation(); ?>
4. Making a POT template file
POT file is a template file consisting information about all translate-able strings in the theme. POT file should be included when distributing the theme so that users can translate the theme themselves by importing it into translation software like PoEdit.
We will use PoEdit in this guide.
First, create a new catalog by clicking File > New catalog and fill in your theme details under “Project Info” tab.
Next, under “Paths” tab, leave the Base Path with a dot. Now, depends on your $path you set just now, you need to let PoEdit know where is your theme’s root folder. eg: Based on our example above, $path is theme-folder/languages/ , so now press “create item” button and enter “../” as the value.
Explanation:
- “../” means one folder up, in relative to base path, thus it is referring to the theme-folder/ directory , because you went one folder up from languages/ folder.
- Another example, if your $path is set to theme-folder/extras/language/ , you need to use “../../” to go two folders up.
Now go to “Keywords” tab, press “create item” button and type “__” (two underscores) as the value. Add another item with value “_e”.
Explanation:
We just told PoEdit what function names to look for. Remember we just applied __() and _e() on all our translate-able strings?
Press okay and save the file into the theme-root/languages/ folder (based on our example) as template.po
Now here’s how the whole process run, PoEdit will now scan through your selected PATH (theme root folder) for the 2 KEYWORDS “__” and “_e” (the 2 wordpress functions we talked about earlier on). When PoEdit finished scanning the folder, you will then be presented with a long list of translatable strings.
Now re-save the clean untranslated po file. Rename it as template.pot and all done! You just created a POT template file.
Note:
You will notice another file called template.mo inside the same folder. MO file is a machine language file that is meant to be read by computer, while PO file is meant to be read by users like us. MO file is being saved along when you save PO file. Delete that file for now since we just need to create a POT template.
5. Translating into PO & MO file
As a theme developer our job is done, but if you want to continue translating your theme into another language, here’s how:
Click File > New Catalog from POT file > choose the POT file you just created. Verify your project Info and press OK to skip Path and Keywords tabs, because there is no change needed on path and keywords.
Save it into the theme-root/languages/ folder (based on our example). The filename must start with the language code, an underscore and the country code. Eg: en_GB.po
After you are done translating all the words, save it and your translation for the theme is ready, provided that IF you already set WPLANG constant value in wp-config.php to your locale, such as en_GB, same as your filename.
Important Note
- The value for WPLANG constant in wp-config.php needs to be exactly same as the filename of po and mo files in order for the translation to take place.
- If your filename is en_GB.po , update wp-config.php like this:
define(‘WPLANG’, ‘en_GB’);- By changing WPLANG’s value, you are telling WordPress to display in another language.
Helpful Links
Translating WordPress – WordPress Codex
ISO 639 Language Codes
ISO 3166-1 alpha-2 Country Codes
If you have any problem translating your theme, feel free to contact me and I will try my best to help.
Big thanks to you, guys!
You ROCKS!
Hi,
If you’re interested to localize web software, PC software, mobile software or any other type of software, I warmly recommend a new l10n tool that my team recently developed and will probably make your work a lot faster and easier:
http://poeditor.com/
POEditor is intuitive and collaborative and has a lot of useful features to help your translations management process, which you can find enlisted on our website.
You can import from multiple localization file formats (like pot, po, xls, xlsx, strings, xml, resx, properties) or just use our REST API.
Feel free to try it out and recommend it to developers and everyone who might find it useful.