How to Internationalize WordPress

Wow! If you wonder what does this post mean, don’t worry you’re not the only one! As you know, WordPress is translated into many languages, but very often plugins or themes contain some strings that aren’t translated into your own language and this is more than frustrating: it’s irritating.

So why this happens? Probably because developers do not use as they should internationalization. That’s to say the use of specific functions included in WordPress that allow an easy way to translate everything.

Step 1 – Loading translation files

The very first step when creating a theme is to load translation files, there are many ways to do it, but the simplest is using this code:

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

When working on a plugin, it’s pretty much the same thing:

function myplugin_init() {
  load_plugin_textdomain( 'my-plugin', false, dirname( plugin_basename( __FILE__ ) ) ); 
add_action('plugins_loaded', 'myplugin_init');

Now that the files are loaded under a “languages” folder, you can create a .pot, or .po file using POedit  free software.

Step 2 – Translating strings

When you need a string be translatable, you need to include the string contain into a function. The most used functions are _e() and __(). Here is a sample of to use __():

echo '<p>' . __( 'This is the string content', 'textdomain' ) . '</p>';

What does this function is returning the string contain, but it doesn’t print it. That’s why we need to use echo. But the _e() function is printing the string contain without using echo or print:

echo '<p>';
_e( 'This is the string content', 'textdomain' );
echo '</p>';

Step 3 – Translating string containing variables

But sometimes your string might contain variables. Using _e() and __() does not work. So, in that case you need to printf() and sprintf() functions. As we saw earlier, printf() echo the string while sprintf() store it.

echo '<p>';
printf( __( 'I bought %d books.' ), $_books_count );
echo '</p>';

echo '<p>';
echo sprintf( __( 'I bought %d books.' ), $_books_count );
echo '</p>';

Step 4 – Strings with more than one variable

In the case of a string containing more than one variable, use the following code:

printf( __( 'I bought %1$s books, and %2$s tomatoes.' ), $books_count, $tomatoes_count );

Step 5 – Dealing with plurals

In the example above i bought books and tomatoes. But what i bought only one book? The code will print “1 books”, and this is not correct. So, to deal with plural, there’s another function called _n(). Here is how to use it:

printf( _n( 'i bought %d book.', 'i bought %d books.', $books_count ), $books_count );

Step 6 – Contexts

Sometimes, a word can have different meanings dues to its context. You can then use these functions _x() and _ex(). The second one echo the string while the first one only store its content. These functions have a second argument to explain it’s context. Fo example if a word is used twice in a page but has different meanings in the content and in the sidebar, then your code would look to something like this:

APPARENT (obvious vs. not clear) — It was apparent to all, Joe was the apparent loser. 
Two different contexts for the word "apparent"

// In the content
echo _x( 'apparent', 'in_content', 'my-plugin-domain' );

// In the sidebar
echo _x( 'apparent', 'in_sidebar', 'my-plugin-domain' );

Step 7 – Javascript internationalization

And finally when you have a string to needs to be translatable in a javascript file you can use a method defined in the codex using wp_localize_script().

// In your PHP file:

wp_enqueue_script( 'script-handle', … );
wp_localize_script( 'script-handle', 'objectL10n', array(
	'speed'  => $distance / $time,
	'submit' => __( 'Submit', 'my-plugin-domain' ),
) );

// in the javascript file:

$('#speed').val('{speed} km/h'.replace('{speed}', objectL10n.speed));

Simply replace your own variables and you’re done!

Post Author: Remi

Remi is an expert WordPress developer that coded many great free and premium themes and plugins. His experience on WordPress allows him to produce great stuff and to propose advanced tutorials.

Disclosure: This page contains external affiliate links that may result in us receiving a comission if you choose to purchase said product. The opinions on this page are our own. We do not receive payment for positive reviews.
Got something to say? Join the discussion.
  1. Pierre SKL says:
    I was actually expecting one more bullet point ;) The idea behind that is being able to offer other languages for your theme/plugin, how can I gather all the translatable text and generate the good .mo/.po files in order to translate them in a different language? Otherwise, good introduction :)
    • AJ Clarke | WPExplorer says:
      AJ Clarke | WPExplorer
      I personally use a program called Poedit which is super easy to use. I think the following post might be a good one for you to check out - Localize & Translate WordPress Themes - its a little older (hence the new article) but the guide for creating the .PO and .MO files is still relevant (even though they have changed the UI of the program).
  2. you've given some instructions above only multi lingual site development. To be honest I have no clue what you have stated above meaning where the above code should be inserted into.
    • AJ Clarke | WPExplorer says:
      AJ Clarke | WPExplorer
      * For the first part literally you can put this code wherever you wish, it just depends how you setup your framework. Functions.php should be fine. * For the actual translation of strings this is done obviously where you want the string to appear on the front end.
  3. Hi, yes as AJ replied, you can place the code in functions.php of wherever you want. All the rest is dispatched in every single file.
  4. Thanks. That will be my next pet project.
  5. SpyroPress says:
    Honestly, this is the most simplest and informative article I have read till for wordpress internationalization. Thanks
    • AJ Clarke | WPExplorer says:
      AJ Clarke | WPExplorer
      That's great news! We are glad you found it helpful ;)

Leave a Reply