Making WP Events Plugin Multilingual

A detailed walk-through based on WPML

Making WordPress Events Plugin Multilingual

This is a description of the approach I have used to make multilingual WordPress sites easier to format and translate. It’s not intended as a how-to guide, as there are so many variables involved, but it’s working very well for me, so I hope it helps you too.

Why it can be hard to style a multilingual site

One of the great advantages of WordPress is that you can quickly add plugins that give you configurable functionality without writing a tonne of code that you will then have to support all by yourself. However most plugins have not been designed with multilingual support and adding extra language fields to a plugin would probably take you so far from the core product that you are effectively on your own again for support.

That’s why I’ve been working on some minimal-code approaches to making all aspects of my sites multilingual. Most of it is done with CSS; a small amount of PHP is also used.

Great plugins to get you started

My research in late 2009 showed the WPML plugin as being really easy for content contributors/editors to use yet powerful enough to satisfy the creator/administrator of the site.

One of the really important things WPML does is to create pages which have the language declaration correct in the HTML header. It also defines a language constant which you can use in PHP, to help those browsers (IE7 and Safari) which don’t recognise all the web standards needed for simple multilingual sites.

I also like the straight-forward usability of the Events plugin by Arnan de Gans. It doesn’t support multiple languages directly, but so long as you aren’t creating hundreds of calendar entries it can be configured easily to go multilingual.

The lang selector – almost perfect

There is almost a perfect way of using CSS to solve all (well many) of your multilingual development challenges. It is the lang selector. Here’s an example of how you can use it in a stylesheet to change a background according to language:

#branding:lang(es) { background url('branding_bg_es.jpg'); }
#branding:lang(en) { background url('branding_bg_en.jpg'); }

This tells the browser to select either an English (en) or Spanish (es) background image for the ‘branding’ div, according to the language of the current page.

Another great way of using the lang selector is to show or hide small chunks of text according to the current page language. With the lang selector, you can wrap your texts with spans to hide them, like this:

<li class="event-title"><span class="text-lang-en">Lunch break</span><span class="text-lang-de">Mittagspause</span></li>

… and use some nifty css to only display the text relevant to the current page, like this:

.text-lang-en:lang(de) { display: none; }
.text-lang-de:lang(en) { display: none; }

This css is telling the browser to hide any element on German pages that has the class text-lang-en and to hide any element on English pages that has the class text-lang-de.

You can extend this principle to anywhere you can specify a style. I’ve found it great in widget titles, text and links in footers and more:

<h3 class="lang-en">A selection of forthcoming Events</h3><h3 class="lang-cy">Pethau sy’n mynd ymlaen</h3>

But where this kind of CSS-based language showing/hiding is most valuable is in places where a plugin or other module is outputting text in a single language but in a way that you can configure…

Configuring events for multilingual display

The WordPress Events plugin allows you to configure ‘templates’ which define exactly how event listings look. Here’s a typical event listing template in just one language:

<li><strong>%title%</strong><br />%startdate%, %starttime%</li>

Now, if only we could get a language tag in there somehow…
There are two ways to go about it:

The crudest would be to put your own markup in each event listing. So for example in the title field you might enter <span class=”lang-en”>Lunch Break</span><span class=”lang-de”>Mittagspause</span>. This works but is not exactly user-friendly.

Better (in my opinion) is to duplicate each event (yes, there’s a button in the events editor to do exactly that) for each language and use the event category to indicate the language.

Say you have two categories of event: ‘Training’ and ‘Presentation’. What you do is modify the categories so you now have:

  • ‘Training lang-en’
  • ‘Training lang-de’
  • ‘Presentation lang-en’
  • ‘Presentation lang-de’

So for each new event that site editors/authors create, they need to specify the language through the appropriate category. Once they have done that, they can click the ‘duplicate’ button, enter the text in the other language and change the category to reflect that language.

The template is now changed to look like this:

<li class="%category%"><strong>%title%</strong><br />%startdate%, %starttime%</li>

The HTML that is generated will look something like this:

<li class="Training lang-en"><strong>Lunch Break</strong><br />20/12/2010, 12:30</li>

Note that the space in the middle of the category name gives you a distinct language identifier separate from the original category descriptor.

With the CSS we saw above, events in the ‘wrong’ language will now be hidden automatically. Just remember that the system is outputting a separate language version of each event, so if you configure the events plugin to limit the number of events displayed, then you will need to set double the number that you want in each language.

Problems with lang and browser compatibility

OK, I mentioned browser issues right at the start, so now it’s time to resolve them.

This time it’s not just Internet Explorer at fault. Although IE7 (plus IE6 and earlier) fail to act on the lang selector, Safari is equally incomplete. So this method, as I’ve just described it, won’t work at all on most Macs and on many PCs.

Fortunately there is a workaround.

Right at the start of this article, I said that the WPML plugin has a constant that you can use in PHP to return the language of the current page. Using this we can tweak the template of our theme (or the child theme if we are using someone else’s template) so that the body declaration includes a style which indicates the language of the page.

I use Thematic as the basis for my themes, but the same principles apply anywhere – you just need to work out where to make your changes in your template. In thematic, the key file is header.php.

Where you see the body declaration you simply append some simple PHP which returns the language constant from WPML, ICL_LANGUAGE_CODE. You can see the modified line below, with the addition market in blue:

<body class="<?php thematic_body_class() ?>lang-<?php echo ICL_LANGUAGE_CODE?>">

The result is that you have a page which includes code with a language indicator at the end:

<body class="wordpress page pageid-38 lang-cy">

So now all we need to do is update our CSS to drop the form :lang(cy) and instead introduce our own language selector:

.lang-cy .english, .lang-en .welsh
{
	display: none!important;
}

And there you have it. An effective way of making mono-lingual plugins and widgets work nicely with multiple languages, with just one line of PHP and not a database modification in site!

Hope it works as well for you as it is for me,

Philip

This entry was posted in Technical stuff. Bookmark the permalink. Both comments and trackbacks are currently closed.