web2ajax : The Blog

juin201001No talk

I’ll show you here how to implement a simple solution to detect and serve content in the visitor language.

For this, I use two web domains, one with a ‘.com’ extension and the other in ‘.fr’
But you can either use it as subdomain, like ‘fr.website.com’ or ‘en.website.com’.
And third solution, only based on a url param and cookies.

Let me explains more below..

First to see an example : check at www.delarueguillaume.com.

How to Implement it ?

What you need :

The first thing we have to do is to detect the visitor language. For this, I’d find a very simple, but efficiently, PHP class named ‘Language’ ( from Jonas Raoni Soares Silva ).

Below, this the code to paste in a new file called « LanguageDetect.php », located in your website directory.

<?php 

//+ Jonas Raoni Soares Silva
//@ http://jsfromhell.com
class Language{
	private static $language = null;

	public static function get(){
		new Language;
		return self::$language;
	}
	public static function getBestMatch($langs = array()){
		foreach($langs as $n => $v)
			$langs[$n] = strtolower($v);
		$r = array();
		foreach(self::get() as $l => $v){
			($s = strtok($l, '-')) != $l && $r[$s] = 0;
			if(in_array($l, $langs))
				return $l;
		}
		foreach($r as $l => $v)
			if(in_array($l, $langs))
				return $l;
		return null;
	}
	private function __construct(){
		if(self::$language !== null)
			return;
		if(($list = strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']))){
			if(preg_match_all('/([a-z]{1,8}(?:-[a-z]{1,8})?)(?:;q=([0-9.]+))?/', $list, $list)){
				self::$language = array_combine($list[1], $list[2]);
				foreach(self::$language as $n => $v)
					self::$language[$n] = +$v ? +$v : 1;
				arsort(self::$language);
			}
		}
		else
			self::$language = array();
	}
}
?>

Auto Detection

1/ Now to detect visitor’s language, we have to load the LanguageDetect class file, like that :

<?php
require 'assets/php/LanguageDetect.php';
?>

2/ Set accepted languages : (for me, French or English)

<?php
$i18n_accepted = array('fr', 'en') ;
?>

3/ And finally Retrieve best match, which give :

<?php
require 'assets/php/LanguageDetect.php';
$i18n_accepted = array('fr', 'en') ;
$i18n_language = Language::getBestMatch($i18n_accepted);
?>

URL Param : $_GET[lang]

If the GET ‘lang’ param is added to url, like ‘www.example.com?lang=fr’, we overwrite the auto detection value.
It’s useful to let visitor choose is language by clicking on country flag by example.

Our code becomes :

<?php
require 'assets/php/LanguageDetect.php';
$i18n_accepted = array('fr', 'en') ;
$i18n_language = Language::getBestMatch($i18n_accepted);
if ( in_array(strtolower($_GET[lang]), $i18n_accepted) ) $i18n_language = strtolower($_GET[lang]) ;
//var_dump($i18n_language); // -> uncomment to see final language
?>

Cookie Store and get preferences

To avoid to send each time the GET[lang] param, you can use cookies to store language.

<?php
require 'assets/php/LanguageDetect.php';
$i18n_accepted = array('fr', 'en') ;
$i18n_language = Language::getBestMatch($i18n_accepted);

// -- If specified in url ?lang=fr, overwrite cookie
if ( in_array(strtolower($_GET[lang]), $i18n_accepted) ) {
	$i18n_language = strtolower($_GET[lang]) ;
	setcookie("lang", $i18n_language, time()+3600,"/");
}
// -- If cookie is setted
if ( in_array(strtolower($_COOKIE[lang]), $i18n_accepted) ) {
	$i18n_language = strtolower($_COOKIE[lang]) ;
}
//var_dump($i18n_language); // -> uncomment to see final language
?>

Translation File Linking :

Basics

We’ll create a file called ‘i18n’. This file will contains translations and a function to return translated output.

<?php

// -- TRANSLATIONS
$i18n = array(

	// -- FRENCH
	'fr' => array(
		'meta_title' => "Guillaume DE LA RUE | CV Développeur, Consultant et Designer WEB",
		'meta_description' => "Bonjour, Je m'appelle Guillaume DE LA RUE, j'habite Rouen (près de Paris) et je suis développeur Web Php/Javascript/HTML/CSS/Mysql.",
		'doc_title' => "Développeur, Consultant et Designer WEB",

		'language_fr_class' => ' class="active"',
		'language_en_class' => '',

		'age' => 'Age',
		'age_value' => '%s years old',

		// ...
	),

	// -- ENGLISH
	'en' => array(
		'meta_title' => "Guillaume DE LA RUE | CV Developer, Consultant and Designer WEB",
		'meta_description' => "Hi, my name is Guillaume DE LA RUE, I lived Rouen (quite near Paris) and I'm a Web Php/Javascript/HTML/CSS/Mysql senior Developer.",
		'doc_title' => "Developer, Consultant and Designer WEB",

		'language_fr_class' => '',
		'language_en_class' => ' class="active"',

		'age' => 'Age',
		'age_value' => '%s ans',

		// ...
	)
) ;

// -- Return i18n translation
function i18n($var = '') {

	GLOBAL $i18n, $i18n_language ;
	$args = func_get_args() ;

	// -- choose language
	if ( empty($i18n_language) ) $i18n_language = preg_match('/\.fr/i', $_SERVER[SERVER_NAME]) ? 'fr' : 'en' ;

	// -- get the good translation
	if ( ! empty($i18n[$i18n_language][$var])  ) {
		$out = $i18n[$i18n_language][$var] ;
	} else {
		$out = $var ;
	}

	// -- if need to use printf
	if ( !empty($var) ) {
		if ( !empty($args[1]) ) printf($out, $args[1]) ;
		else echo $out ;
	}

	// -- return language
	return $i18n_language ;

}
?>

How to use

To call a translated value, use this code :

<?php 

i18n('meta_title') ; // -> will output the title meta tag in the visitor language
i18n('age_value', 29) ; // -> will output a printf output, replacing %s by the first param
i18n(); // -> without param, i18n will return the current language

?>

Language manual switch :

HTML Code

Now, we’ll add a switch bar, containing flag icons and links to each translated version.
I use the famfamfam_flag_icons pack for flags : download it

Not that I use « i18n(‘language_fr_class’) » to insert the active class on correct flag.
All that in your main html template gives :

<div id="language" class="lightrounded">
	<a href="http://www.delarueguillaume.fr/?lang=fr" title="Voir le site en Français"><img src="/img/famfamfam_flag_icons/png/fr.png" <?php i18n('language_fr_class') ?>></a>
	<a href="http://www.delarueguillaume.com/?lang=en" title="View the website in English"><img src="/img/famfamfam_flag_icons/png/us.png" <?php i18n('language_en_class') ?>></a>
</div>

CSS linked code

.lightrounded {
	-moz-border-radius:5px;
	-webkit-border-radius: 5px;
	-o-border-radius: 5px;
	border-radius: 5px;
}
#language {
	padding: 5px 10px;
	position: absolute;
	right: 30px;
	top: 5px;
	background: #525252;
	background: rgba(52, 52, 52, 0.7);
}

#language img { border: 1px solid #777; }
#language img.active { border: 1px solid #fff; }

Example :

You can check an example on www.delarueguillaume.com.
Firstly you should be in french if you are french, else in english.
And you can change language by click on top site flags.

Hope that this post will help you a day :)

Pas de commentaire

Pas encore de commentaire.

LEAVE A COMMENT