Menu Search
Jump to the content X X
Smashing Conf Barcelona

You know, we use ad-blockers as well. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. our upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

Internationalizing And Localizing Your WordPress Theme In 6 Steps

An important part of developing a WordPress theme is to prepare it so that users from every corner of the planet can translate its messages to any language. This article covers the basics of internationalization, which is the process of designing a theme in such a way that the end user can adapt it to various languages without having to change the source code, and localization, which is the process of translating text messages to a particular language. Expanding the range of our theme’s users is a big deal, and WordPress provides a simple way to do that.

(Image: somegeekintn2)

Overview of Process Link

Here is a brief overview of the process of internationalizing and localizing a WordPress theme:

  1. Load a text domain,
  2. Process text messages with WordPress functions,
  3. Extract these messages with the appropriate software,
  4. Provide a translation for each message,
  5. Create a language file for a particular locale,
  6. Instruct WordPress to enable localization and to load the language file.

Adding WordPress Functions Link

The first thing to do is load a text domain by adding the following line in the functions.php file of our theme:

load_theme_textdomain('mytheme', get_template_directory() . '/languages');

The first argument must be a unique identifier (a good practice is to use your theme’s name); it defines the theme’s domain, as the text for translation will not be in WordPress’ core translation files. The second argument defines the folder of the language files. To load these files, the function must be tied to the after_setup_theme action:

add_action('after_setup_theme', 'my_theme_setup');
function my_theme_setup(){
    load_theme_textdomain('mytheme', get_template_directory() . '/languages');

Processing Text Messages Link

After editing functions.php, the next step is to look through the source files, find the messages that need to be translated and process them with the appropriate WordPress function. The two most important and commonly used are _e($text_message) and __($text_message). The first function searches for the translation of $text_message and prints it. If the translation does not exist, then it prints $text_message. This function is used for text messages that are not in PHP functions, as it prints the result. Take the following line:

echo ‘Hello user’;

This should be transformed to:

_e(‘Hello user’,’mytheme’);

The second function searches for the translation of $text_message and returns it. If a translation does not exist, then it returns $text_message. It is used for text that is in PHP functions. For example:

the_content( ‘Read more’ );

This function call should be transformed to:

the_content( __(‘Read more’,’mytheme’) );

Sometimes, a text message includes dynamic data, such as a number from a PHP variable. In this case, we use the sprintf PHP function to produce the final message string:

$results_found = 12;
$message = sprintf( __(‘%s results found’ , ‘mytheme’) , $results_found );

Singular and Plural Link

WordPress provides a function for singular and plural translation of the same text message:

_n( $single, $plural, $number, $domain )

The first argument is the text that will be used for singular, and the second is the text that will be used for plural. The third argument is the number to compare in order to decide which to use.

Although the _n() function is built into WordPress, using it is discouraged because the translation software parses only the first parameter of a function, and so these two text messages would not be fetched. Instead, we can use the PHP if statement:

if($results_found == 1)
    $message = __(‘1 result found’ , ‘my-text-domain’);
    $message = sprintf( __(‘%s results found’ , ‘my-text-domain’) , $results_found );

Language Files Link

Once we ensure that we’ve processed every text message with the functions mentioned above, our theme is ready for translation. For this purpose, there are three types of language files:

  • The POT file contains a list of all translatable messages in our theme.
  • The .po file is created when we translate a POT file to a particular locale.
  • The .mo is a binary file that is created automatically by translation software and is not human-readable.

Messages List Link

The first thing to do is create a POT file, which contains all of the text messages of our source files and which will be the file that the translator uses to translate the messages to another locale. There are several tools for creating POT files. The most popular, and the one we will use in this article, is a cross-platform tool called Poedit7.

  1. Open Poedit, and create a new catalog.
  2. Fill in the project’s information in the “Project info” tab:
    Project info tab of Poedit
  3. In the “Paths” tab, identify the folder for Poedit to search for source files that contain translatable text messages. These folders are relative to the folder of our language file, so if we save the file in a folder in our theme folder, then we should add ..:
    Paths info tab of Poedit
  4. In the “Keywords” tab, define the WordPress functions used to translate messages (keep in mind that Poedit is not only for WordPress). In our theme, the two keywords we used are __ and _e.
    Keywords info tab of Poedit
  5. After you click “OK,” Poedit will scan the folders you’ve provided in the Paths tab and will list the text messages in the source files.
    Messages list in Poedit8
  6. Save the POT file in a folder named languages in your theme directory:
    Languages directory with POT file

Please note: WordPress does not need a POT file to load a particular translation. The file is just a template that contains all of the translatable message strings, which you can provide to the translator to translate and return to you as a .po file.

Providing Translation Link

Our POT file is now created! The next step is to translate the messages of this POT file to a particular locale and then save it as a .po file:

  1. Select the string you want from the list, and type the translation into the field at the bottom of the window.
    Type translation for a text message in Poedit9
  2. Repeat this action until all messages have been translated.
  3. Save the file as a .po file in the same folder, setting the language code and country code as the file name (sometimes they are identical), as defined by ISO 639-110 and ISO 3166-111, respectively. For example, if the language of the translation is British English, then the name would be en_GB.po. Now, the languages folder will contain the .po and .mo files of our translation as well as the POT file:
    Languages directory with .po files

Please note: When saving a .po file, Poedit will automatically create an .mo file, which is a binary file and is not human-readable.

Updating the Configuration File Link

Once we’ve created the .po and .mo files, it’s time to instruct WordPress to enable the localization and to load the language files. Edit the wp-config.php file in WordPress’ root folder, and set the WPLANG variable to the relevant locale. For example:

define('WPLANG', '');

If we’re using the British English locale, then we would change the line above to:

define('WPLANG', 'en_GB');

What About Plugins? Link

Although this article deals with WordPress themes, it’s worth mentioning that the differences in the process of internationalizing a plugin are minor. Similar to what we did, we tell WordPress where to find the language files by adding the following function in the plugin’s main file:

load_plugin_textdomain('myplugin', false, basename( dirname( __FILE__ ) ) . '/languages' );

The first parameter defines the text domain; using the plugin’s name is recommended, as it must be unique. The second parameter defines a path of a folder, where the .mo file resides. It corresponds to a deprecated function that was valid until WordPress 2.7, so we specify it as false. The third parameter is the folder where the language files reside (in this case, we assume they are located in a directory named languages).

To load the language files, we need to add a hook and tie this function into the init WordPress action:

function myplugin_internationalization()
    load_plugin_textdomain('myplugin', false, basename( dirname( __FILE__ ) ) . '/languages' );
add_action('init', 'myplugin_internationalization');

Finally, we process the text messages the same way as before, using the _e($text_message) and __($text_message) functions. After we’ve processed all of the text messages, our plugin is ready for localization.

Conclusion Link

WordPress’ user base is growing rapidly, making the CMS one of the most popular tools in the world of Web development. With people coming from all over the world and speaking different languages, WordPress offers a flexible platform and provides an easy method of internationalization, enabling users to translate with no modification to the source code.

Other Resources Link

This article covers the basics of internationalizing and localizing a WordPress theme. For more in-depth information, have a look at the following related resources, available in the WordPress Codex12:


Footnotes Link

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14

↑ Back to top Tweet itShare on Facebook

Konstantinos Kouratoras is a software engineer based in Crete, Greece. WordPress lover and amateur photographer. You can contact him through personal website or follow him on twitter.

  1. 1

    But it runs only for the core and theme of WordPress, and for the content that we will create in posts and pages? I had to buy a plugin to make all this things one time….

    • 2

      The internationalisation and localisation of themes and plugins usually refers to only to text within the theme itself (in the WordPress admin and on the front-end). Translation for your content is a whole separate task.

  2. 3

    Great introduction for theme (and plugin) developers. It’s important to realise that when you release a theme into the general public, not everyone speaks your language! There are many more people who may want to use your theme, and why not? :)

  3. 4

    Great article, I actually developed a plugin for content localization and was looking for a solution translating theme functions.

  4. 5

    How come there are so little comments?

    Very good explenation! The best i’ve come across since i was reading myself into making themes translate ready.


  5. 6

    Interesting read!

    Currently I’m trying to trigger a language change, when a single-page-post opens.. I’d like to check if a post belongs to a category (I would devide my posts in language categories) & then change the current wordpress language.. I’m guessing I need to do this in functions.php

    Any advice you can perhaps give me ?

    thanks in advance!!

  6. 7
  7. 8

    Nice Article.. Helped me to make theme translation ready. Thanks! :)

  8. 9

    Hi! Good tutorial. You should know that it’s also possible to use this online tool to translate WordPress themes – There’s even a plug-in you can use with it to integrate its API to your WordPress account so that you save more time with the file management process – I highly recommend it.

  9. 10

    My theme is the Adventure theme, and the plugin is installed and activated and it does not remove the “and comments are closed” from my pages.

  10. 11

    I’d like to share this tool I’m using to help translating several open-source projects, it’s called Transifex. I’s basically an online PO editor with team management for several languages. With one account I can manage, coordinate and/or translate several projects. Powerful and easy to use, a must-have tool to any serious multi-language project.

    It’s free to open-source projects, and paid for private projects.

  11. 12

    Is it necessary to make the .po and .mo file when creating a theme? When looking at the default wordpress themes they only include to .pot. As a theme developer, would I only create the .pot?

  12. 13

    thank you, Konstantinos. by far the clearest explanation/instructions i’ve found on the web for this matter, but i have a question in 2014… will the gist of this still work for WP 3.8.1? thanks again!

  13. 14

    This was a great explanation. I’m wondering about dates and WordPress generated words like categories, comments, etc. I’m trying to keep the dashboard running in english, so I’m thinking doing the language on the theme is the way to go, but I’m not sure how the dates will come out.


↑ Back to top