Wednesday, March 24, 2010

Multiple Languages - a “How-To” using PutYourLightsOn’s Multi-Language module

I’m building a dual-language website now that will feature English and Dutch, and I’ve been digging and culling information on this for a few weeks now. I’m putting my experiences down into this “How-To” help others stuck at 2am.

The focus on this is specifically using the Multi Language Module from PutYourLightOn but there are enough smaller tips in here that it’s worth putting in one place. There are also other means to do multiple languages that don’t require a commercial module, but this worked for me. YMMV. If this isn’t the right place, admins, let me know and I’ll move it.

Caveats:
• This was developed for the EE 1.6x but it should be very similar in 2.1x installations
• Requires the use of jQuery for the Control Panel extension and the commercial Multi-Language Module from PutYourLightsOn.net
• This presumes 2 languages, but more can be used following the guide
• We try for pure EE-solutions whenever possible - no hacking or php/js and exposing the security
• Since we’re describing EE tags, normally they can’t be displayed inline (because the system immediately processes them). Using the code tag will ruin the reading, so when you see something like [base_path] realize the parenthesis are replaced by brackets.

Start - Setting-up the different language paths and removing the index.php from the URL:

We’re presuming you have a default language (in my case English) set in your General Preferences > Site Language setting. All you need to do is add the module, add the extra languages and add some files to make sure the [base_url] starts out of the correct path.

• Install the module (follow the directions on that - easy enough)

• Add a additional language in the module using the correct ISO 639-1 code for your extra language (en = english, nl = dutch, es = spanish, etc)

• Add a directory to the root of your site for each additional language using the matching ISO 639-1 code. This is always lower-case.

• Modify your path.php file to add 2 new variables [base_url] & [user_language]. The important bit is at the bottom:

$global_vars = array(); // This array must be associative 

changes to point to your default language (replace “mysite” with your site and your particular base language)

// $global_vars = array(); // This array must be associative
    
$global_vars = array(
    
"base_url" => "http://www.mysite.com/"
    
"user_language" => "en"
    
); 

• Now add .htaccess to the root using the EXCLUDE LIST method of removing the index.php. You’re including only the directories you want the system to look into:

RewriteEngine on
RewriteCond 
$!^(nl|css|images|system|themes|index\.php[NC]
RewriteRule 
^(.*)$ /index.php/$1 [L] 

• The module comes with spanish and italian directory file example - use one of them and move the 3 files to the server
- index.php = you can leave alone
- .htaccess = modify the path in the Rewrite Rule to point to your desired language, in my case it’s Dutch

RewriteRule ^(.*)$ /nl/index.php/$1 [L] 

- path.php = modify the last lines like the above default language, but this time to add the new language path

$global_vars = array(
    
"base_url" => "http://www.mysite.com/nl/"
    
"user_language" => "nl"
); // This array must be associative 

There are enough folks out there having trouble with removing index.php - removing two of them is worth pointing out. This caught me a few times.

The module’s instructions are clear enough; there are 2 basic methods for language replacement: the tag method, where you add a tag via the module and it does the swapping:

{exp:multi_language:phrase index="hello"

and Conditionals based on your current [base_path]:

{exp:weblog:entries weblog="my_weblog"}
{if user_language 
== "en"}{title}{if:else}{title_{user_language}}{/if}
{
/exp:weblog:entries} 

You’ll note that it uses the default [title] but also an alternative [title_] field. In my custom fields, right after title I’ve added a title_nl field, keeping the lowercase iso convention. This is the method of doing dynamic content - each language element having its own field (I loop through using a FieldFrame set, for example).

Links are your first enemy in multiple languages, so you need to find an alternative to [permalink] and [auto_path]. Let’s re-write that example to add a link:

{exp:weblog:entries weblog="my_weblog"}
<a href="{base_url}template_dir/template/{url_title}">
  
{if user_language == "en"}{title}
  {if
:else}{title_{user_language}}
  {
/if}
</a>
{/exp:weblog:entries} 

So what happens here is that depending on your current [base_path], the link does away with the [title_permalink] and rebuilds the path from the root up to the article. If I had a templates directory called “site” and in there an article view page called “view”, it’d look like this:

<a href="{base_url}site/view/{url_title}">
  
{if user_language == "en"}{title}
  {if
:else}{title_{user_language}}
  {
/if}
</a

Pagination doesn’t use [title_permalink] but rather [auto_path]. Specifically for Pagination, you’d want to add a new [paginate_base] parameter to your [entries] tag:

{exp:weblog:entries weblog="workshops" limit="5" status="open" 
paginate_base="{if user_language != 'en'}{user_language}
{/if}/template_group/template"

This points the Pagination auto links used by [if next_page] [if previous_page] to the correct language.

The next time you’ll see [auto_path] is in a site search, and unfortunately there doesn’t seem to be a similar method for a search_base. What I’ve done in this situation is to use the weblog_id to point me to the correct category link:

{if weblog_id == "3"}
  
<td width="30%" valign="top"><b><a href="{base_url}site/static/{url_title}">{title}</a></b></td>
{if:elseif weblog_id == "4"}
  
<td width="30%" valign="top"><b><a href="{base_url}site/workshop/{url_title}">{title}</a></b></td>
{/if} 

and then just use different results pages for each language.

Calendars are a bugger too - I’m working on a solution here, but it looks to be one where you’ll have to check segment_1 and then use swapping method on days and months. When I have that sorted, I’ll add it here.

Anyway, that’s my solution. Remember that many conditionals can slow you down, so I built many blocks to reduce the number of queries and conditionals. Depending on your needs, it might make mode sense to just check once if you’re in a language, then spill all the right fields out, instead of doing it on a field-by-field basis. All said though, this system is quite robust and I’m really happy with it.

As I learn new things I’ll add them here. The developer Ben at PutYourLightsOn has been amazingly helpful, working out many problems in my particularly wonky situation. Hopefully this will reduce his support workload a little. 

If anyone has more ideas, solutions or questions concerning languages and working with this module, please add them below.  Cheers!

Posted by admin on 03/24 at 08:53 AM
Posted in: IT notes   Project 52  
Permalink
Page 1 of 1 pages