How to make a translatable WordPress theme

by Jean. 60 Comments -

Althought English is the most represented language over the Internet, it is a good thing to think about people who speak other languages and offer them trabslated WordPress theme. In this step-by-step tutorial, you’ll learn how to take a WordPress theme and make it translatable for any language.

1 – Add the needed functions

Let’s start by the basics: Paste the following lines of codes on your functions.php file.

load_theme_textdomain( 'Cats Who Code', TEMPLATEPATH.'/languages' );
 
$locale = get_locale();
$locale_file = TEMPLATEPATH."/languages/$locale.php";
if ( is_readable($locale_file) )
	require_once($locale_file);

On line 1, you see the load_theme_textdomain() function. This function allow you to load a Text Domain. You can pick up any name, but keep in mind that it have to be unique. So the best practice should be to use your theme name.

2 – Internationalize your theme

For translating our WordPress theme, we’re going to use the php gettext functions.
GetText has two functions: _e and __ (two underscores).
The “_e” function is used to print “simple” text, and the __ function is used when the text to be displayed is already wrapped in php tags.

Examples:

<?php _e("The page you're looking for doesn't exist", "Cats Who Code"); ?>
<?php the_content(__('Read more...', "Cats Who Code")); ?>

Notice again the text domain name (Cats Who Code) above, remember that it should be the same as in the functions.php file.

The boring part is that you have to replace each single string by the required function. Depending on how many strings your theme have, this can take a lot of time. I’ve heard of some GNU tools to easily extract strings from files, but as I never tried it I can’t say anything about it. For those interested, google xgettext.

3 – Create your .po file

Now, your WordPress theme can easily be translated to any languages. But to display text in a foreign language, you have to add a .po file.
.po files stands for Portable Object. basically, theses files contains a string, and its translation in another language. For example, if you download the French version of WordPress, you’ll have a fr_FR.po file in the archive. This file contains all the translations needed for your theme to speak French, so your theme will say Bienvenue instead of Welcome.

Good news, you don’t have to search throught your theme files for all the string to be translated. A free online tool named icanlocalize.com can scan PHP files and create .po files for you ICanLocalize will extract all strings wrapped in __("txt", "domain") and _e("txt", "domain") calls. Strings can be enclosed in either double quotes (“) or single quotes(‘) and with any character encoding.

Po files can be edited with PoEdit, a free software especially dedicated to that task:
PoEdit

As you probably guessed, you have to translate each text string. Once you translated it all, save the .po file. PoEdit will also generate a .mo file, which is basically a compiled version of the .po file.

4 – Implementation

Right now, you have done the most “difficult” part of the job. The only thing you have to do is to define your WordPress locale.
To do so, the first thing to do is to get your language and country code. For example, if your language is French and France is your country of residence, your code will be fr_FR. The GNU gettext manual contains pages to help you find both your country and language codes.

Once you have your codes, open your wp-config.php file and look for the WPLANG constant. If it exists, simply replace the existing code by yours. If it doesn’t exists, simply paste the following line (with your own code, of course)

define ('WPLANG', 'fr_FR');

Sources

The following articles has been very useful to me for writing this post. Thanks to the authors.

 

Comments (60) - Leave yours

  1. Ozh said:

    I strongly recommend *not* to use something as “Cats Who Code” as the textdomain, but preferably something like “catswhocode”. A textdomain with spaces (and mixed case) is a loud call for file problem depending on the platform.

  2. Frank said:

    Use the plugin Localization and you have no problems and many support at the translation: different files for frontend and backend, automaticly transaltion via Google API and more, the best tool for translate a plugin or theme.

    @ozh: right, it must use a string without empty and -

  3. tkhobbes said:

    Interesting – but I am actually looking at something that would CHANGE the language, based on the client browser’s preferences…. is there something like that available (I guess I would have to build upon the solution here and add stuff to detect the client’s language)…

    Obviously, the challenge would be to create at least the static pages 1x per language and then select them dynamically…

  4. Konstantin said:

    Notice again the text domain name (Cats Who Code) above, remember that it should be the same as in the functions.php file.

    I usually solve this problem by defining a contant with a unique name and use this constant in the load_theme_textdomain() function and all gettext functions.

  5. Spicy Web Design said:

    Another way to make translatable WordPress themes is to create a WordPress child theme using a parent theme framework such as Thematic that has the translation capability already built in.

    http://www.spicywebdesign.com/so-you-want-to-create-wordpress-themes-huh-the-remix/

  6. Ralph MIller said:

    What affect does this have for search engines? Is each translation have it’s own unique URL? Or does it maintain it’s URL structure and just translate the page? We offer search engine ranking services, but I haven’t encountered anything regarding multi-language websites, so I’m very curious if this has any added value from a marketing perspective..

  7. Milch said:

    Hey!

    Whats the best way to make a multi language wordpress blog? I tried some plugins but none of them really impress me. Does anyone have any experiences with this and any good advice?

  8. Rene said:

    for some reason I get:
    “Fatal error: Call to undefined function load_theme_textdomain() in /home/content/01/5138501/html/blog/wp-includes/functions.php on line 27″

    anyways regarding a good tool for wordpress translation I use WPML widget and it is phenomenal!!

  9. JesperA said:

    Hi, i have some problem when using the comments_popup_link function in WordPress with multiple values like this:

    comments_popup_link(‘No comments’, ’1 comment’, ‘% comments’);

    How do i implement the translating feature into that?

  10. Chris said:

    Hi Jean,

    Thanks for the great post/site.

    I have a quick question. I would like to know where to keep the langauge (.mo,.po) files? Do i just keep them inside the theme folder? I already have a language folder that contains the relevant language files for wordpress but I want to know where to keep these files that translates my theme.

    Best wishes,

    Chris

  11. anmari said:

    Hi,

    You may want to update this bit:

    The boring part is that you have to replace each single string by the required function. Depending on how many strings your theme have, this can take a lot of time.

    If you have a plugin (and possibly this is there for themes too) hosted in wordpress. Login, go to the admin section for your plugin
    eg: http://wordpress.org/extend/plugins/amr-ical-events-list/admin/

    There is a box to
    1) enter a text-domain
    2) browse to your php file,

    hit submit and Voila you have all your __ and _e and _x calls updated with the text domain in new file.

    Works for any php file (does not appear to have to belong to the plugin!). WP probably should put this somewhere more central!

    • George Dina said:

      Or you can use add-textdomaina.php to update all your gettext string with the correct domain.

      Details here:
      http://codex.wordpress.org/I18n_for_WordPress_Developers#Marking_strings_in_themes_and_plugins

  12. Timo said:

    I don’t understand this line:
    $locale_file = TEMPLATEPATH.”/languages/$locale.php”;

    Why include a PHP-File? In Twentyeleven’s functions.php, it is the same code. But they don’t have any PHP-Files in the languages-Folder. What the heck?

  13. jahur said:

    Hi,
    your article helps me lot.

    _e(“txt”, “domain”) . Can you tell me what is “domain”? I want to translate my theme into french. Will it be fr_FR?

    Thanks

    • Aziz said:

      Domain is the text domain that declared in first step (Add the needed functions). In this tutorial it is ‘Cats Who Code’.

  14. Jonas Lundman said:

    Nice and clean get started explained turtorial about how to translate a WordPress theme. Thanks. Its getting old and as mentioned in this thread, maybe you should edit the article about Text domain names and whitespaces. What I understand, the codex recommend using dashes like cats-who-can, am I right?

Leave a Reply

Your email address will not be published. Required fields are marked *

Please respect the following rules: No advertising, no spam, no keyword in name field. Thank you!