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:
$('#submit').val(objectL10n.submit);
$('#speed').val('{speed} km/h'.replace('{speed}', objectL10n.speed));
Simply replace your own variables and you’re done!