How to make a "multilingual" WordPress blog without multilingual plugins

2011-04-14 » apache, Wordpress

Around October 2010 I migrated from Drupal to WordPress my bilingual websites Stop and Strider. Eighteen months later, WordPress has confirmed to be better than Drupal for my own needs, as far as those two websites are concerned (I still stick to Drupal for other websites).

There is, however, one part of those WordPress websites that has just become a big problem for me, and is how to keep them (looking) multilingual. I think I have found a solution for it and have explained it here for two reasons. First if I am right, this trick will be probably useful to many other WordPress users. The other is caution. I said I think I have a solution: I have done a little testing on a dummy installation (see below) and everything seems to work. However, before implementing it on the actual blogs, I’d really like to have some feedback from the community, just to make sure I am not forgetting something important (which I may have very well done).

When I started those two websites, I wanted them to have one name/base URL as simple and short as possible, so that I could just tell people “go to stop.zona-m.net” and then they would immediately find the version in their language, versus “go to {it,en}.stop.zona-m.net”. English content would have URLs like stop.zona-m.net/2010/11/article-title/, while all Italian content would have the /it/ suffix, as in stop.zona-m.net/it/2010/11/article-title/ and there would be automatic links from each version to the other. Drupal 6 does this, no problem.

Do you REALLY need a multilanguage blog?

When I moved to WordPress the best way to keep this architecture with one Wordpress install seemed, and very likely is, the WPML plugin with English as primary language. After a while, however, I realized that WPML doesn’t seem to do all I need and had in Drupal. This may be my own fault but, for example, I found no way in WPML to:

  • use language-dependent widgets, ie how to tell WPML that a certain widget, e.g. an RSS feed, must be shown only in the English or Italian version of each page (update 2011/04/15: Amir, one of the WPML maintainers, points out in the comments to this post that this is now possible with WPML and it is explained here)
  • link to each other, as Drupal lets you do, the different names in each language of each category, in order to have automatic links between, for example, http://stop.zona-m.net/category/digiworld/ and its italian equivalent http://stop.zona-m.net/it/category/digimondo/, or to have automatic preselection of the right categories in the new target language when you translate an existing article.

In addition to this, I also realized something more important. Very likely, no matter how cool it looks, I don’t really need the links with the nice flags between english and italian versions of each page. By this I mean that my readers don’t really need it and almost never use it, because almost all of them only use the website in only one language.

Finally, at the beginning of 2011, WPML announced it would become a commercial/proprietary product. Putting all this together made me decide to find another solution.

Making two copies of WordPress look like one bilingual website



Those two websites run on a Virtual Private Server, on which I can add databases, change apache settings and so on as much as I want. This and all I explained in the previous section made me consider splitting each one of those websites in two independent, monolanguage WordPress installs. The result would be something a little bit less convenient to manage for me than it was with WPML, but nothing substantial, and almost transparent for all my readers.



As long, of course, as no URL changes in the migration! I want all the English URLs to remain the same (no problem) but I also do NOT want to “lose” or change the italian URLs. Here's how I have achieved this on a test install, please tell me if there are weaknesses!



I have set up a test bilingual blog at bits.zona-m.net, with the same versions of WordPress and all the plugins as the real websites, in the /var/www/html/wp/tips directory, associated to the wp_tips MySql database and with this Apache server configuration:



<VirtualHost :80>
ServerAdmin marco@digifreedom.net
DocumentRoot /var/www/html/wp/tips
ServerName tips.zona-m.net
AccessFileName .htaccess
CustomLog logs/tips.zona-m.net.access.log combined
ErrorLog logs/tips.zona-m.net.error.log
</VirtualHost>



Then I created a few posts in it, both in English and Italian, with links to each other, to have something meaningful on which to test the following method.



In order to split that WordPress bilingual blog in two independent ones without breaking any URL already created, first I cloned its MySql database:



# mysqldump -u root -p wp_tips > ~/dumb_wptips_bilingual.sql
# mysql -u root -p
> create database wptips_it;
> use wptips_it;
> source /root/dumb_wptips_bilingual.sql;
> GRANT ALL PRIVILEGES ON wptips_it.
TO "sameuser_ofwptips"@"localhost" IDENTIFIED BY "password";



then I duplicated the whole, already working WordPress installation of tips.zona-m.net to another directory:



cp -r -p /var/www/html/wp/tips /var/www/html/wp/tips_it



and modified the wp-config.php file in tips_it to point at the wptips_it database. Next, I modified the Apache configuration to “fetch” all and only the URLs starting with http://tips.zona-m.net/it from that second directory. In order to do this it is necessary to create an alias in the httpd.conf file:



<VirtualHost *:80>
ServerAdmin marco@digifreedom.net
DocumentRoot /var/www/html/wp/tips
ServerName tips.zona-m.net
Alias /it /var/www/html/wp/tips_it
AccessFileName .htaccess
CustomLog logs/tips.zona-m.net.access.log combined
ErrorLog logs/tips.zona-m.net.error.log
</VirtualHost>


and to modify the .htaccess files in the two folders as follows:



# more /var/www/html/wp/tips/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# more /var/www/html/wp/tips_it/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /it/
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /it/index.php [L]
</IfModule>
#

At that point, “all” was left was to convince the cloned WordPress installation in tips_it and its MySql database wptips_it that they now live at another base URL with the it/ suffix, that is tips.zona-m.net/it. It seemed to me that the simplest/safest method in this case among those recommended in the official Change the WordPress URL page is the one called “Edit functions.php”. So I added these two lines to the functions.php file of the active theme:

  # cat /var/www/html/wp/tips_it/wp-content/themes/twentyten/functions.php
  <?php
  /*
  update_option('siteurl','http://tips.zona-m.net/it');
  update_option('home','http://tips.zona-m.net/it');
  */
  /**
   * TwentyTen functions and definitions
   *

then, as the WordPress page above recommends, I loaded the admin page a couple of times and immediately after I removed those two lines. Last but not least, I deactivated English in WPML in the “Italian” blog and Italian in the “English” one. Done! Apparently, everything works, as you can check by yourself by going to http://tips.zona-m.net and http://tips.zona-m.net/it. All the URL created when there was only one bilingual WPML/WordPress install are still valid with the same website URL: you can still visit both http://tips.zona-m.net/2011/04/here-we-go-with-my-second-english-post/ and http://tips.zona-m.net/it/2011/04/versione-italiana-del-secondo-post/, even if they are now served by different copies of WordPress. The only thing that has been lost, but as I said I do wonder if I really needed it, are the links between the several versions of each page.

If this works, I will migrate the real websites to this structure, deactivate/remove WPML completely, then upgrade both of them to the last version of WordPress, customized their layout separately and go on. The only things I should lose are, I believe:

  • possibility to handle posts in both languages from the same browser window. Worth the hassle for me, if it both maintains the old URLs and lets me customize each language at will
  • clear signs for Italian visitors that there is also an English version of each website and vice-versa. I feel that just adding a link in the top menu bar to the home pages of each language should be enough, since I’m pretty confident that almost nobody so far actually used both two languages
  • (totally wild guess, not sure if this really is an existing issue) search engines temporarily pissed off and de-ranking each post because it doesn’t have links from the version in the other language???

What do you think? Have I missed something? Is there any security hole or other weakness that will come and bite me if I migrate the real website? Should I do something else? Please let me know!