Building a Bilingual WordPress CMS

Some of you may not know that I’m a Website Designer and I’ve recently been working on a project for the Welsh charity WAMES (The Welsh Association of ME & CFS Support).

The website they want had quite a few specific requirements, but as usual budgets were tight so I had to build a site that met these requirements without adding too much cost. In addition to many other features, the site had to be accessible, easy to use, fully featured and also had to be built around a Content Management System (CMS). On top of this it had to be fully bilingual as well.

To keep costs down I decided to use the OpenSource CMS WordPress as it is free and most importantly easy to use for the clients allowing them to update the site whenever they wish without needing to know anything about website development. The most involved part was going to be making it bilingual.

The Bilingual Alternatives

I had several options that could be used to make a Bilingual installation of WordPress.


I’d used a Bilingual plugin for WordPress before called Gengo. It had worked OK, but it wasn’t ideal. For a start it no longer works with the latest versions of WordPress and secondly although it allowed you to add content in different languages, linked the alternative language pages and created navigation menus in the various languages, all pages within the site (whatever language they were in) used the same theme. This meant that anything within the theme such as text or links in the header or footer weren’t translated.

Other Plugins

There are other plugins for WordPress such as Bilingual WordPress that offer very basic bilingual functionality. This one simply adds an additional alternative language field into the add a post page of WordPress that allows you to add a translation. Once again it doesn’t create a full alternative language version of the site, just a translation of the content. There are a number of plugins that work along these lines.

Others work by using an on the fly computerised translation – OK in a pinch I guess but not really useful for a full bilingual website.

Roll My Own Bilingual WordPress

The option I finally decided upon was to roll my own bilingual WordPress installation. The plan was to create two WordPress installations, one for the English site and one for the Welsh site. I was then going to use the ‘Custom Fields’ feature of WordPress to link pages between the two sites.

So, this is what I did.

1. Multiple WordPress Install

First of all I created two separate WordPress installations on the web-server. The English version was in a directory called ‘wordpress-english’, the Welsh version in a directory called ‘wordpress-cymraeg’. I set them up so that they both used the same MySQL database but the database tables had different suffixes; wpenglish_ and wpcymraeg_ respectively.

There are detailed instructions on the WordPress codex outlining the installation of  Multiple Blogs Through Multiple Installs.

2. Separate Themes for Each Language

One of the main advantages of having two separate WordPress installations is that I had two completely separate theme directories and could therefore create individual themes for each language. This allowed me to make sure the entire site was bilingual. If I had wanted to I could have used different colour schemes for each language as well just to distinguish between them.

3. Using the Custom Field to link alternative language pages.

To make the website fully bilingual I wanted to make sure that visitors to the site could change from one language to the other from anywhere within the site and be taken to the relevant page in the alternative language. It would be easy to simply have a ‘English’ button on all of the Welsh pages that takes people to the home page of the English site, but this wasn’t good enough. If someone was deep in the hierarchy of the Welsh site and wanted to go to the English site they should ideally be taken to the corresponding page, deep in the hierarchy of the English site, and vice versa.

I therefore used the ‘Custom Field‘ feature of WordPress to achieve this. On both sites I created a new custom field called ‘Alt_Lang_ID’. Now, when creating a page or post within WordPress it is an easy task for the person editing the site to add the name of the corresponding page in the alternative language to the value of this ‘Alt_Lang_Id’ custom field.

As an example:

The Home page on the English site has the URL:

The translation of this on the Welsh site is a page called Cartref which has the URL:

So, to link the two I put the word ‘cartef’ into the Alt_Lang_ID field on the English site and the word ‘home’ into the Alt_Lang_ID field on the Welsh site.

Note: I was using Mod_Rewrite to rewrite permalinks using the Month and Name option within WordPress so it was this part of the URL that had to be added to the Alt_Lang_ID custom field. If using the default WordPress settings then the post ID would be inserted here.

4. Creating links between the alternative languages

So, we’re nearly there, we have two completely separate WordPress installations, one for the English version of the site and one for the Welsh version of the site. We also have a simple way of identifying which pages and posts correspond to each other between the two sites. Now all we have to do is create a link that connects the two.

I decided to place the link in the header of each site by simply modifying the header.php file within the theme. First I needed to select the Alt_Lang_ID data from the database so that I knew what the corresponding page was on the alternative language site. The example below shows the code from the Welsh version of the site, linking to the English version. A similar approach was used to link them in the other direction too:

/* Get post ID for link to English Site from Alt_Lang_ID custom field */
$alt_post_id = $post->ID;
$lang_id_result = mysql_query("SELECT `meta_value`FROM `wpcymraeg_postmeta` WHERE `post_id` = $alt_post_id AND `meta_key` = 'Alt_Lang_ID' LIMIT 1");
$alt_lang_id = mysql_fetch_array($lang_id_result);

Now it was just a matter of creating an HTML link and placing it where I wanted it within the header:

$alt_lang_link == ''; // Reset the link
//Only add the link if an alternative page is specified
if ($alt_lang_id['meta_value'] != '') {$alt_lang_link = $alt_lang_id['meta_value'];}
{echo '<p class="lang_link"><a href="'.$alt_lang_link.'" title="View this page in English">English &raquo;</a></p>'; }

And that was it, a fairly easy way to create a bilingual WordPress website. Not only does each language have its own theme that can be customised individually but it is easy to link relevant pages or posts from each language to their corresponding pages and posts in the other language. There was no need to modify or add anything to the core of WordPress as we used the custom field feature to create an association between the languages and only had to modify the theme in order to add the links between them.

The site isn’t live yet and it hasn’t been tested in earnest but I think it is going to work just the way my clients want it to.

10 Responses

  1. Avatar forComment Author Charlie says:

    I’ve been testing different setups to get a bilingual WP site going. Did your solution work out?

    • Avatar forComment Author Alan says:

      Hi Charlie,
      It seems to be woking perfectly at the moment. The site in question will have a couple of hundred pages so it isn’t live yet as we’re still waiting for some of the content and some of the translations but the bil-lingual side of things seems to be working well.

  2. Avatar forComment Author Mario says:

    why not using 2 different databases with one installation.

    if $_session[lang] == en $database = wp_english
    else $database = wp_german

    first install the english, then copy the database and include the language link in the frontend. fill the content in both db’s.

    you can also modify then the admin with a menu to select the databases.

    you can even go farther, that you select specific tables in dependence on the session language in just one database.

    • Avatar forComment Author Alan says:

      Yep, I guess that would work too, but I’d still need to create a separate theme for each language as well and would still have the issue of linking one post / page in one language to the same post / page in the other language. I’d imagine this would still have to be done manually by the administrators of each language as each database would end up with its own post ids etc.. This is even more pronounced when using title based permalinks as the titles are obviously different from one language to another.

      One installation and 2 databases may have certain advantages, but having two installations was just as easy. The main issue was linking posts and pages from one language to the same posts and pages of the other language, which is where using the Custom Fields came in. I think I’d still need to do that with your solution anyway?


  3. Avatar forComment Author Jormungand says:

    Thank you very much for the tutorial, it works like a charm… but I have one question:

    What can we do to link categories in different languages since they don’t have custom fields?

    • Avatar forComment Author Alan says:

      Good question, and I’m not sure of the answer… I don’t use categories on the site that I’ve used this Bilingual technique on, so I haven’t really tried a way of doing it. Someone else might have though?


  4. Avatar forComment Author Alopex says:

    Hi Alan,

    Excellent tutorial. Can you please explain how to modify this script in order to show a default link (eg. the home page) when there is no alternative page specified in the custom field?


  5. Avatar forComment Author Alopex says:

    Sorry. It was a dump question!

    I think it would be:

    $alt_lang_link == ''; // Reset the link
    //Only add the link if an alternative page is specified
    if ($alt_lang_id['meta_value'] != '') {$alt_lang_link = $alt_lang_id['meta_value'];}
    {echo 'English »’; }

    {echo ‘English »’; }


  6. Avatar forComment Author Daniel says:

    Great job. The problem is that the link is displayed also in taxonomy and categories if there is a post with a meta_value for ‘Alt_Lang_ID’.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Avatar forComment Author

Alan Cole

Alan is a Freelance Website Designer, Sports & Exercise Science Lab Technician and full time Dad & husband with far too many hobbies: Triathlete, Swimming, Cycling, Running, MTBing, Surfing, Windsurfing, SUPing, Gardening, Photography.... The list goes on.

You may also like...