Internationalization should be common practice, not a feature


A subject finally getting some attention in the WordPress community is i18n, or internationalization.

Internationalization is the process of making an application ready for translation. Often this gets confused with localization, which is the process by which the text on the page and other settings are translated and adapted to another language and culture.

Both internationalization and localization are equally important within WordPress, but there cannot be any localization if the theme or plugin has not been internationalized first. Therefore it is of utmost importance for WordPress theme and plugin developers to internationalize their software, regardless of whether it ever actually receives a translation into another language.

In the past couple of months we have seen more and more articles being published on the subject of internationalization. Some are even dripping with frustration!

I must admit that I have left frustrated comments on sites like WPCandy, WPBeginner, WPMU and the like, whenever something is promoted that is not properly internationalized. It seems I finally got someone’s attention as Ryan is the one who asked me to write this editorial after I left yet another frustrated comment on one of the articles published here.

For those whose native language is not English and who want to develop websites in more than one language, it is very frustrating to read any news about Fantastic Hypothetical Theme A or Cool Plugin B that were just released, only to realize after downloading that it is actually completely useless since it hasn’t be internationalized!

And do you know what is even worse? When said theme or plugin costs money (often called premium). Not only is that frustrating, it’s just wrong. Despite the number of features your theme or plugin has, if it has not been internationalized it shouldn’t be sold in the first place.

This is just not open for discussion. Internationalization should be common practice, not a feature!

But then again…

It actually is not that strange that for many developers internationalization comes as an afterthought. If you look at the Theme Development Standards article in the WordPress Codex, you will see that all the way down, somewhere at the bottom is a quick note about internationalization:

To ensure smooth transition for language localization, use the gettext functions for wrapping all translatable text within the template files. This makes it easier for the translation files to hook in and translate the titles into the site’s language.

“This makes it easier”? Without it, the theme is impossible to translate! Anyone interested in this part of the standards will need to do lots of additional reading.

I believe that because WordPress is primarily an American invention and most popular blogs that cover WordPress are put together by people that reside in the USA, one can unfortunately safely assume that internationalization is not high on anybody’s priority list.

After all, English is the primary language in use on the web, right?

In reality it’s not. The world is larger than the North America. As a matter of fact, as of December 2011 English is being used by only 27% of (online) users worldwide; that is a bit more than one-quarter of the total internet population (via Wikipedia).

I ask you to briefly consider the following: If you are a premium theme developer who properly internationalized your themes, your potential market would instantly increase by four times.

That convinced you, now didn’t it?

Implementation tips

The best part is that internationalizing your themes is actually quite easy.

First, I would suggest you add the textdomain to your theme and to set up a special directory for additional languages. For this to work you need to add the following lines to your functions.php file:

On line 4 you see mytheme. This is going to be your textdomain and you will need to replace this with the name of your theme. If your theme name is very long, you can also use something shorter. Make sure that it is unique.

If you are using a child theme you should replace load_theme_textdomain with load_child_theme_textdomain.

If you would actually also localize your WordPress theme and offer it with a few additional languages on launch, you would add the .mo files of these languages to the languages directory.

After setting up the textdomain, next is the actual internationalization of the strings in your theme.

First up is displaying translated text. Let’s have a look at the theme Sunny Blue Sky, which is one of the most recent themes (at time of writing) added to the WordPress Theme Directory.
Via the theme SVN we can have a peek at the theme’s files and we hit the jackpot at the first available file: the 404.php:

The correct way of writing these strings is:

That wasn’t so hard, now was it?

Next up is processing the translated text. To show this I use a string in the functions.php file:

To internationalize this, we change the strings as follows:

Also not super tough, right?

It does actually get a bit more complicated than this as there are more possibilities to write strings; without getting into too much details – after all this information is widely available online – I will list the most common ones below:

The WordPress Codex has a great tutorial with basically all the options available. The textdomain is all the way at the bottom, so please keep that in mind.

Remember that after you have done it once, the second time will be easier, and the third time even easier than that, and so forth. Furthermore there is plenty of information available online and there are people who can help you with it too (for instance the WordPress forums).

Once you have fully internationalized your theme, you will need to make a .pot or .po file, so translators can do their work and add .mo files per translation. You can include this default .po file by adding it to your languages directory.

POEdit is a handy tool that you can use to generate .pot, .po and .mo files of your internationalized theme or plugin. Smashing Magazine published an article on the subject not too long ago, so I’d suggest referring to that.

Additional resources

If you’re looking for additional reading on this topic, I recommend:

24 thoughts on “Internationalization should be common practice, not a feature

  1. At last.
    On a daily basis I turn down purchase/use of great premium/free product X.
    People will translate your product for you if you internationalize it !!
    Thanks for this.

    Also please put up a proper howto/reference page we can point people to on wpcandy.
    With a how to for themes and plugins. And maybe expand on how to generate the base .pot file

  2. Pingback: Guest Post on WP CandyWP i18n

  3. Great article Piet. Not proud to admit it but I have been guilty of not doing this in the past but started getting my act together not long ago. 🙂

  4. Great guide that addresses a quite substantial issue. I’m glad you brought up this topic, and I really hope developers are going to take internationalization & localization more seriously than it appears to be nowadays.

    • Codestyling Localization is the way to go. It’s useful enough to be mentioned in an article such as this.

      Localization is really an issue. I’ve had to discard several themes and plugins, because they were not properly localized. I don’t expect plugins to speak my native language of Finnish, but they’re unusable if I’m not able to translate the critical lines myself. Usually there are not that many lines to translate, because admins do understand english, and don’t mind it popping up in the admin area.

  5. “The correct way of writing these strings is”

    Actually, the correct way would also include consistently writing the code to the WP Coding Standards, including the whitespace love inside of ( and ), and ideally including some DocBlock documentation, even for simple examples, since these omissions are as important to some groups of users as i18n is to the (vastly larger) group that you want to help.

    That aside, internationalizing theme or plugin code is really simple, and I’m glad to see an article on WP Candy which aims to remind (or raise the curiosity of) developers about this simple task which can vastly increase their market potential.

    One of the annoying things is when all the strings are internationalized, yet no load_plugin_textdomain (or the various equivalents for themes) call is made – that one line of code is 50% of the problem!

    • You’re right about the WP Coding Standards, I’ll try to keep that in mind for next time, Gary.

      To prevent the problem you describe in your last sentence, I recommend to always start by adding the textdomain to your theme or plugin.

      • I do, for all my code. And despite Mark Jaquith’s post to the contrary, I always use a class property oe simple method as the text domain argument in the i18n calls, and have yet to come across any situation where a string is not picked-up – that allows me to amend all of the text domains in one go should there ever be a conflict, or allow, say, plugin text domain to be filtered so it matches a theme text domain, should a developer ever want to do that.

        My point was that even major theme shops are doing all but that one line of loading domain code, and don’t seem to realise that it’s just as important as wrapping all the strings in the relevant functions, despite requests from myself, David (referenced in your post) and other prominent i18n bods within WP.

        • Gary, that sort of practice also makes it really, really difficult for people writing tools to use your code.

          Do not use variables as the text-domain. Really. Please. Pretty please. For me. Okay?

          • What sort of tools do you mean? As yet, no one has given a clear example of when a string has failed to be detected when a variable, constant, function or static method is used. Convince me, pretty please?

  6. Making code i18n ready is dead easy. It’s just that it’s cumbersome to write (printf(“some string”, “somedomain”) vs echo(“some string”)) and cumbersome to maintain (“hey, someone sent me a .po & .mo file, let’s update the plugin and commit once again”)

    It’s just i18n vs lazyness 🙂

    • Well let’s then just hope that especially in the case of paid-for themes and plugins i18n wins over laziness otherwise it very easily becomes i18n vs stupidity 😀

  7. Pingback: WordPress Community Roundup for the Week Ending February 11 - Charleston WordPress User Group

  8. I’m in a situation where it’s very difficult to internationalize the plugin I’m working on. I’m using an API which retrieves its results in English and I’m using fairly complex JS that dynamically outputs several messages on the front end. There’s nothing in this article that mentions how to internationalize JS.

    • You are right that I haven’t mentioned anything regarding JS, I just don’t know enough of it to mention anything that would help you.
      Probably you already have see them, but the Codex mentions something as well as an article on Mozilla

Comments are closed.