Prime Your WordPress Theme for i18n

internationalization

A whopping two-thirds of the more than 27 million active WordPress websites originate outside of the United States1, so it shouldn’t be hard to see that internationalization is now more important than ever. Translation plugins like WPML streamline the business of translating, but if your custom theme (or plugin) isn’t primed correctly, not only will you not be able to take advantage of easy translation utilities, you’re effectively excluding the bulk of your theme’s target audience. The good news is prepping your theme for localization is pretty straightforward.

Establish Your (Text) Domain

This value, set in your theme’s main stylesheet, is a unique identifier used by WordPress to load the appropriate translations. In general, the text domain should match the slug used for your theme (or plugin).

/*
Theme Name: cre8
Author: cre8, LLC
Author URI: https://www.cre8media.com/
Description: Translation-ready WordPress theme.
Version: 1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: cre8
Domain Path: /languages
*/

The Domain Path is the directory translation files are stored in, and defaults to the languages folder within your theme.

To load your theme’s translations, call load_theme_textdomain() in your functions.php file, typically from within the after_setup_theme action hook:

<?php
add_action( 'after_setup_theme', 'cre8_after_setup_theme' );
 
function cre8_after_setup_theme(){
    load_theme_textdomain( 'cre8', get_template_directory() . '/languages' );
}

Make Your Strings Translatable

Next, review your theme files and replace any hard-coded strings with WordPress translation functions. __() is used to retrieve a translated string, while _e() will echo the string directly.

For example, this…

<p>Comments are closed</p>

becomes…

<p><?php _e( 'Comments are closed.', 'cre8' ); ?></p>

Know Which Translation Function To Use

In the example above, it’s pretty clear why the localized string was echoed directly using the _e() function, but when should you use __() or any of the other dozen or more translation functions?

If your string utilizes a variable placeholder, then you should retrieve that value and pass that to __() and use PHP’s printf() function for final parsing.

So instead of…

<p>Written by <?php the_author(); ?></p>

we have…

<p><?php printf(
    __( 'Written by %s', 'cre8' ),
    get_the_author()
); ?></p>

Context Matters

Since some words may have multiple meanings in a particular language, the context in which it is used is important for anyone doing the work of translating. To disambiguate, you can use _x() or _ex(). These are similar to their __() and _e() counterparts except that they accept an additional $context argument.

For example, to differentiate between the noun “design” and the verb “design”:

<?php _ex( 'design', 'noun', 'cre8' ); ?>
<?php _ex( 'design', 'verb', 'cre8' ); ?>

Return on Investment

Taking the extra steps to internationalize only adds to the value of your theme or plugin, and means you don’t need to be a polyglot to reach a potential user halfway across the world. And that makes sense in any language.

1. WordPress Usage Statistics