Continuing the discussion above regarding multi-lingual sites, I'd like to add a third method of handling them -
UPDATE:
This method now has a new addon that should make the process of implementing it much simpler -
viewtopic.php?f=5&t=109793. Creating a separate editable region for each languageAs opposed to the solution above where we give each language a separate template, this method requires only a single template.
Pros:
Does not clutter the sidebar with multiple templates.
Does not require the user to upload static assets (e.g. images, files etc.) multiple times - one for each language.
Might be easier to implement
Cons:
There will be a single URL for any given page for all the languages - this could have SEO implications.
Likewise, comments of all languages will appear on the same page.
As you can see, this method is not without limitations but, anyways, it is always good to have choices and there will be cases where this method would be the best.
How it works:For simplicity let us suppose we have a template that requires only two editable regions - one for an image and other for content.
This could be our initial single-language version -
- Code: Select all
<?php require_once( 'couch/cms.php' ); ?>
<cms:template>
<cms:editable name="photo" type="image" />
<cms:editable name="content" type="textarea" />
</cms:template>
<h1>Language Test</h1>
<p> <img src="<cms:show photo />" /> </p>
<cms:show content />
<?php COUCH::invoke(); ?>
Let us suppose we need to have the content in three different languages - English, French and Spanish.
What we do is, instead of creating a single editable region, we create three editable regions - one for each language.
Thus our template will now look like this -
- Code: Select all
<?php require_once( 'couch/cms.php' ); ?>
<cms:template>
<cms:editable name="photo" type="image" />
<cms:editable name="content_en" type="textarea" />
<cms:editable name="content_fr" type="textarea" />
<cms:editable name="content_es" type="textarea" />
</cms:template>
<h1>Language Test</h1>
<p> <img src="<cms:show photo />" /> </p>
<cms:show content />
<?php COUCH::invoke(); ?>
Notice how instead of one region for the content, we now have three - each suffixed
by a language identifier.
Also notice that we still have a single image region.
Next
just suppose for the time being that we set a variable named 'my_lang' somewhere at the beginning of our code that contains the name of the selected language - the value could be either 'en' or 'fr' or 'es'.
- Code: Select all
<cms:set my_lang ='fr' 'global' />
We can now easily display content in the selected language by using a simple conditional like this -
- Code: Select all
<cms:if my_lang='en'><cms:show content_en /></cms:if>
<cms:if my_lang='fr'><cms:show content_fr /></cms:if>
<cms:if my_lang='es'><cms:show content_es /></cms:if>
Our template now becomes -
- Code: Select all
<?php require_once( 'couch/cms.php' ); ?>
<cms:set my_lang ='fr' 'global' />
<cms:template>
<cms:editable name="photo" type="image" />
<cms:editable name="content_en" type="textarea" />
<cms:editable name="content_fr" type="textarea" />
<cms:editable name="content_es" type="textarea" />
</cms:template>
<h1>Language Test</h1>
<p> <img src="<cms:show photo />" /> </p>
<cms:if my_lang='en'><cms:show content_en /></cms:if>
<cms:if my_lang='fr'><cms:show content_fr /></cms:if>
<cms:if my_lang='es'><cms:show content_es /></cms:if>
<?php COUCH::invoke(); ?>
Of course, since we have manually hard-coded 'my_lang' to 'fr' in our example, our code will always show the French version of the content. We'll fix that soon - for now let it be the way it is.
So as you can see from the code above, instead of a single <cms:show variable_name /> statement, we now have to use as many statements as there are languages - each within a conditional.
If this seems tedious, you can use the following single statement instead -
- Code: Select all
<cms:get "content_<cms:show my_lang />" />
If 'cms:get' seems unfamiliar to you, please take a look at the documentation.
It is slightly different from 'cms:show' in that it takes a string as its parameter and so we can fabricate a string dynamically as we did in our example above.
The <cms:get "content_
<cms:show my_lang />" /> will evaluate to
<cms:get "content_en" /> if my_lang is 'en' and
<cms:get "content_fr" /> if it is 'fr'.
As you can see, you may have any number of languages but you'll only require to use only one 'cms:get' statement.
Following is our template using the alternative method of displaying content-
- Code: Select all
<?php require_once( 'couch/cms.php' ); ?>
<cms:set my_lang ='fr' 'global' />
<cms:template>
<cms:editable name="photo" type="image" />
<cms:editable name="content_en" type="textarea" />
<cms:editable name="content_fr" type="textarea" />
<cms:editable name="content_es" type="textarea" />
</cms:template>
<h1>Language Test</h1>
<p> <img src="<cms:show photo />" /> </p>
<cms:get "content_<cms:show my_lang />" />
<?php COUCH::invoke(); ?>
So the 'my_lang' variable holds the key to our solution - if it can be dynamically set to the user's preferred language, the template will automatically show content in that language.
In the files attached with this post, you'll find a snippet named 'lang_getter.html'.
This is its complete content -
- Code: Select all
<cms:php>
session_start();
global $accepted_langs, $selected_lang;
// Set your languages here
$accepted_langs = array( 'en', 'fr', 'es' );
if( isset($_SESSION['lang']) && in_array($_SESSION['lang'], $accepted_langs) ){
$selected_lang = $_SESSION['lang'];
}
else{
$selected_lang = 'en'; // Set your default language here
}
</cms:php>
<cms:set my_lang = "<cms:php>global $selected_lang; echo $selected_lang;</cms:php>" 'global' />
Place 'lang_getter.html' within your couch installation's 'snippets' folder as we'll embed this in our template (we could have pasted the code directly in the template but we'll be reusing the code in all other templates of our site so it is better to embed it).
What the code does is - it checks if the user has saved his preferred language (in session) and that the language is one of the acceptable languages of our site (please make sure to modify this array to the languages your site caters to)
- Code: Select all
// Set your languages here
$accepted_langs = array( 'en', 'fr', 'es' );
If no language has been selected (will happen when the user visits the site for the first time), it selects a default language (make sure to change this too)
- Code: Select all
$selected_lang = 'en'; // Set your default language here
Finally, it sets a variable for Couch named 'my_lang' that contains the preferred language.
Yes, it the same 'my_lang' variable that we manually set in our example.
So now we can substitute that line of code in our template where we hard-coded 'my_lang' with an embed to this snippet -
- Code: Select all
<?php require_once( 'couch/cms.php' ); ?>
<cms:embed 'lang_getter.html' />
<cms:template>
<cms:editable name="photo" type="image" />
<cms:editable name="content_en" type="textarea" />
<cms:editable name="content_fr" type="textarea" />
<cms:editable name="content_es" type="textarea" />
</cms:template>
<h1>Language Test</h1>
<p> <img src="<cms:show photo />" /> </p>
<cms:if my_lang='en'><cms:show content_en /></cms:if>
<cms:if my_lang='fr'><cms:show content_fr /></cms:if>
<cms:if my_lang='es'><cms:show content_es /></cms:if>
<!-- Alternate method of showing variable -->
<br />
<cms:get "content_<cms:show my_lang />" />
<?php COUCH::invoke(); ?>
OK, but how does the visitor gets to choose and save his preferred language in session?
This is the final piece of the puzzle and then our solution is complete.
We make use of two scripts (both attached below)
1. A snippet named 'lang_switcher_menu.html'
We'll embed this file in our template (don't forget to save it within Couch's 'snippets' folder) to create a language selection menu.
2. A standalone PHP script named 'switch.php'.
Make sure to place 'switch.php' within your Couch installation folder (along with Couch's core files).
This script will do the job of persisting the visitor's selected language in session (apart for sanitizing the supplied parameters as a security measure).
The 'lang_switcher_menu.html' simply outputs an HTML list showing the available languages to the visitor
- Code: Select all
<!-- lang selector menu -->
<ul id="lang_selector">
<cms:php>
global $accepted_langs, $selected_lang;
foreach( $accepted_langs as $lang ){
$selected_class = ( $lang==$selected_lang ) ? ' selected' : '';
echo'<li class="'.$lang.$selected_class.'"><a href="<cms:show k_admin_link />switch.php?lang='.$lang.'&redirect='.urlencode($_SERVER["REQUEST_URI"]).'"><span>'.strtoupper($lang).'</span></a></li>';
}
</cms:php>
</ul>
Let us embed this to create a menu in our template and
we get the final version of our multi-lingual template-
- Code: Select all
<?php require_once( 'couch/cms.php' ); ?>
<cms:embed 'lang_getter.html' />
<cms:template>
<cms:editable name="photo" type="image" />
<cms:editable name="content_en" type="textarea" />
<cms:editable name="content_fr" type="textarea" />
<cms:editable name="content_es" type="textarea" />
</cms:template>
<cms:embed 'lang_switcher_menu.html' />
<h1>Language Test</h1>
<p> <img src="<cms:show photo />" /> </p>
<cms:if my_lang='en'><cms:show content_en /></cms:if>
<cms:if my_lang='fr'><cms:show content_fr /></cms:if>
<cms:if my_lang='es'><cms:show content_es /></cms:if>
<!-- Alternate method of showing variable -->
<br />
<cms:get "content_<cms:show my_lang />" />
<?php COUCH::invoke(); ?>
You can embed 'lang_switcher_menu.html' anywhere on your template to create the language selection menu but make sure to embed it below the 'lang_getter.html'.
The menu is generic enough to be styled anyway you desire but you can also modify it to create your own version.
The important thing to note is that when a visitor clicks on any of the shown languages, the 'switch.php' script is invoked. 'switch.php' persists the selected language in session and then redirects the visitor to the page he used the menu from.
And that is it. That was the final version of our multi-lingual template.
It might have seemed like a very long tutorial but essentially it only consisted of
1. Placing 'lang_getter.html', 'lang_switcher_menu.html' within Couch's snippets folder and placing 'switch.php' within Couch's main installation folder .
2. Embedding 'lang_switcher_menu.html' in our template to create a language selection menu.
3. Embedding 'lang_getter.html' somewhere at the top of our template to find out the selected language.
4. Creating multiple editable regions (one for each language).
5. Outputting the value from the right editable region taking into consideration the selected language.
Hope this helps.
Do feel free to contact us if you have any questions.