A web developer's blog. PHP, MySQL, CakePHP, Zend Framework, Wordpress, Code Igniter, Django, Python, CSS, Javascript, jQuery, Knockout.js, and other web development topics.

WordPress: Multi-language translation for your theme

Although, there are more advanced multi-language plugins like qTranslate available, this post will deal with basic translations in your theme. Like for example, if you want to translate a “hard-coded” English strings in your theme.


… translated into French, will display:


when you have something like http://mysite.com?lang=fr_FR in your URL bar.

Start easy
Let’s start with the simple string above. Instead of directly outputting the string, do it like this:

    echo '<h1>'.__('Programs').'</h1>'

So, what does the double underscore (“__”) mean? The double underscore is a GetText call. There are two ways you can do a GetText call, the other way is:

    _e('Programs'); //This echoes the directly to the browser.

We use the GetText call to output the translated strings.

The translated strings
The translation are stored in a .pot file. It is a text file that looks like this:

msgid ""
msgstr ""
"Content-Type: text/plain; charset=utf-8n"
"Content-Transfer-Encoding: 8bitn"
"Project-Id-Version: n"
"POT-Creation-Date: n"
"PO-Revision-Date: n"
"Last-Translator: wenbert n"
"Language-Team: n"
"MIME-Version: 1.0n"

#: single.php:21
msgid "Programs"
msgstr "Programmes"

#: single.php:30
msgid "Contact Us"
msgstr "Contactez-nous"

You can choose to generate this file manually or use this to extract the GetText calls in your PHP files.

Generating the .mo (Machine Object) file
Once you have all the string translations in your .pot file, you will need to generate a .mo file for it. You will need POEdit to do this. It is a simple and straight forward program. You just need to import the POT file and then save it.

Save all of your files inside the “languages” folder inside your theme folder.

    .. index.php
    .. single.php

Triggering the translation
Put this code in your functions.php file.

add_filter( 'locale', 'my_theme_localized' );
function my_theme_localized($locale) {
    if (isset($_GET['lang'])) {
        return $_GET['lang'];
    return $locale;
load_theme_textdomain( 'my_theme', TEMPLATEPATH . '/languages' );

What it does is that if $_GET['lang'] is set in the URL — and let’s say the value is set to “fr_FR” (http://mysite.com?lang=fr_FR), WordPress will look for the “fr_FR.mo” file.

Please note that this post tackles the subject in a VERY rough way. You should read further here and here — both sites were used as reference for this post!

This entry was posted in General and tagged , , , . Bookmark the permalink.

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>