-
Notifications
You must be signed in to change notification settings - Fork 7.6k
CodeIgniter 2.1 internationalization i18n
Category:Internationalization Category:Core::Language Category:Libraries::Internationalization Category:Libraries::Language
[b]Internationalization (i18n) for CodeIgniter 2.x[/b] is small modification to: [url]http://maestric.com/doc/php/codeigniter_i18n[/url] to work with CodeIgniter 2.1. [h2]Credits:[/h2] Original Author: [b]Jérôme Jaglale[/b]. Original Post (and instructions): [url]http://maestric.com/doc/php/codeigniter_i18n[/url]. Modifications by [b]Yeb Reitsma[/b] [i]Placeholders substitution in language strings[/i]: [b][url=http://codeigniter.com/member/40637]alvil[/url] (original wiki page: [url]http://codeigniter.com/wiki/Placeholders_substitution_in_language_strings/[url])[/b] [h2]What it does:[/h2] Use [url=http://codeigniter.com/user_guide/libraries/language.html]CodeIgniter's Language Class[/url] through the language in the URI: [pre]http://example.com/en/welcome http://example.com/es/welcome[/pre] with the possibility to add placeholders ("%s") inside your language strings, to make it more dinamic. [h2]Installation and configuration:[/h2] [h3]1. Use pretty URLs (without index.php)[/h3] a) With Apache it's usually achieved with [b]mod_rewrite[/b] through an .htaccess. (See [url=http://codeigniter.com/user_guide/general/urls.html]CodeIgniter User Guide for URLs[/url] for more information about this)
b) In [b].application/config/config.php[/b] set to blank [pre]$config['index_page'] = ””[/pre]
[h3]2. Create [b]application/core/MY_Lang.php[/b]:[/h3] [code] <?php (defined('BASEPATH')) OR exit('No direct script access allowed');
// Originaly CodeIgniter i18n library by Jérôme Jaglale // http://maestric.com/en/doc/php/codeigniter_i18n // modification by Yeb Reitsma
/* in case you use it with the HMVC modular extension uncomment this and remove the other lines load the MX_Loader class */
//require APPPATH."third_party/MX/Lang.php";
//class MY_Lang extends MX_Lang {
class MY_Lang extends CI_Lang {
/**************************************************
configuration
***************************************************/
// languages
private $languages = array(
'en' => 'english',
'de' => 'german',
'fr' => 'french',
'nl' => 'dutch'
);
// special URIs (not localized)
private $special = array (
"admin"
);
// where to redirect if no language in URI
private $uri;
private $default_uri;
private $lang_code;
/**************************************************/
function MY_Lang()
{
parent::__construct();
global $CFG;
global $URI;
global $RTR;
$this->uri = $URI->uri_string();
$this->default_uri = $RTR->default_controller;
$uri_segment = $this->get_uri_lang($this->uri);
$this->lang_code = $uri_segment['lang'] ;
$url_ok = false;
if ((!empty($this->lang_code)) && (array_key_exists($this->lang_code, $this->languages)))
{
$language = $this->languages[$this->lang_code];
$CFG->set_item('language', $language);
$url_ok = true;
}
if ((!$url_ok) && (!$this->is_special($uri_segment['parts'][0]))) // special URI -> no redirect
{
// set default language
$CFG->set_item('language', $this->languages[$this->default_lang()]);
$uri = (!empty($this->uri)) ? $this->uri: $this->default_uri;
$uri = ($uri[0] != '/') ? '/'.$uri : $uri;
$new_url = $CFG->config['base_url'].$this->default_lang().$uri;
header("Location: " . $new_url, TRUE, 302);
exit;
}
}
// get current language
// ex: return 'en' if language in CI config is 'english'
function lang()
{
global $CFG;
$language = $CFG->item('language');
$lang = array_search($language, $this->languages);
if ($lang)
{
return $lang;
}
return NULL; // this should not happen
}
function is_special($lang_code)
{
if ((!empty($lang_code)) && (in_array($lang_code, $this->special)))
return TRUE;
else
return FALSE;
}
function switch_uri($lang)
{
if ((!empty($this->uri)) && (array_key_exists($lang, $this->languages)))
{
if ($uri_segment = $this->get_uri_lang($this->uri))
{
$uri_segment['parts'][0] = $lang;
$uri = implode('/',$uri_segment['parts']);
}
else
{
$uri = $lang.'/'.$this->uri;
}
}
return $uri;
}
//check if the language exists //when true returns an array with lang abbreviation + rest function get_uri_lang($uri = '') { if (!empty($uri)) { $uri = ($uri[0] == '/') ? substr($uri, 1): $uri;
$uri_expl = explode('/', $uri, 2);
$uri_segment['lang'] = NULL;
$uri_segment['parts'] = $uri_expl;
if (array_key_exists($uri_expl[0], $this->languages))
{
$uri_segment['lang'] = $uri_expl[0];
}
return $uri_segment;
}
else
return FALSE;
}
// default language: first element of $this->languages
function default_lang()
{ $browser_lang = !empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? strtok(strip_tags($_SERVER['HTTP_ACCEPT_LANGUAGE']), ',') : ''; $browser_lang = substr($browser_lang, 0,2); return (array_key_exists($browser_lang, $this->languages)) ? $browser_lang: 'en'; }
// add language segment to $uri (if appropriate)
function localized($uri)
{
if (!empty($uri))
{
$uri_segment = $this->get_uri_lang($uri);
if (!$uri_segment['lang'])
{
if ((!$this->is_special($uri_segment['parts'][0])) && (!preg_match('/(.+)\.[a-zA-Z0-9]{2,4}$/', $uri)))
{
$uri = $this->lang() . '/' . $uri;
}
}
}
return $uri;
}
}
// END MY_Lang Class
/* End of file MY_Lang.php / / Location: ./application/core/MY_Lang.php */ [/code]
Add your languages to the "$language" array. [b]The first language will be the default language[/b].
[h4]Special URIs:[/h4] A special URI is not prefixed by a language. The root URI (/) is by default a special URI.
You might need other special URIs, like for an "admin" section, which would be in just one language.
Add "admin" to the "$special" array.
Now, links to "admin" won't be prefixed by the current language.
[h3]3. Create [b]application/core/MY_Config.php[/b]:[/h3] [code] <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
// Originaly CodeIgniter i18n library by Jérôme Jaglale // http://maestric.com/en/doc/php/codeigniter_i18n //modification by Yeb Reitsma
/* in case you use it with the HMVC modular extention uncomment this and remove the other lines load the MX_Loader class */ //require APPPATH."third_party/MX/Config.php";
//class MY_Config extends MX_Config {
class MY_Config extends CI_Config {
function site_url($uri = '')
{
if (is_array($uri))
{
$uri = implode('/', $uri);
}
if (function_exists('get_instance'))
{
$CI =& get_instance();
$uri = $CI->lang->localized($uri);
}
return parent::site_url($uri);
}
}
// END MY_Config Class
/* End of file MY_Config.php / / Location: ./application/core/MY_Config.php */ [/code]
[h3]4. Add routes[/h3]
Add these lines to [b]./application/config/routes.php[/b]:
[code]// URI like '/en/about' -> use controller 'about'
// '/en', '/de', '/fr' and '/nl' URIs -> use default controller
[h3]5. Creating languages files[/h3] As explained in [url=http://codeigniter.com/user_guide/libraries/language.html]CodeIgniter's Language Class user guide[/url]. Read this carefully to learn how to load, store and write language files.
You can add [b]placeholders[/b] inside your strings. For instance, if you like to add the "username" to a string, you can by writing this lang string: [code]$lang['welcome'] = "Welcome, %s.";[/code]
See [b]7. Create View[/b] for further reference.
[h3]6. Create Controller[/h3] [code]<?php class About extends Controller {
function index() { // you might want to just autoload these two helpers $this->load->helper('language'); $this->load->helper('url');
// load language file $this->lang->load('about');
$this->load->view('about'); } }
/* End of file about.php / / Location: ./application/controllers/about.php */[/code]
[h3]7. Create View[/h3] To fetch a lang line or add an anchor: [code]
<?=lang('about.gender')?>
<?=anchor('music','Shania Twain')?>
[/code]Read [url=http://codeigniter.com/user_guide/helpers/language_helper.html]CodeIgniter's Language Helper user guide[/url] to learn more on how to fetch language lines.
In case you use placeholders inside your language strings, you can use them like this: [code]
<?php $username = "John Doe"; echo lang('welcome', $username)?>
[/code]This should appear like: [code]Welcome, John Doe.[/code] (Using the language string of step 5)
That's all. Try it, it should work!
[h2]Notes[/h2]
-
You might need to [b]translate some of CodeIgniter's language files[/b] in system/language. Example: if you're using the “Form Validation” library for French pages, translate system/language/form_validation_lang.php to system/application/language/french/form_validation_lang.php.
-
Links to internal pages are prefixed by the current language, but links to files are not: [code]site_url('about/my_work'); // http://mywebsite.com/en/about/my_work
site_url('css/styles.css'); // http://mywebsite.com/css/styles.css[/code]
-
Get the current language: [code]$this->lang->lang(); // en[/code]
-
Switch to another language: [code]anchor($this->lang->switch_uri('fr'),'Display current page in French');[/code]
[h2]Further information and useful modifications[/h2]
- [url=http://codeigniter.com/forums/viewthread/197965/#930928]Avoid Spider Bots problems with "$_SERVER['HTTP_ACCEPT_LANGUAGE']"[/url]
[h2]Disclaimer[/h2] It works on a scratch installation of CodeIgniter 2.0.3, on MAPM 2.0.3 (localhost) in Mac OS X 10.7.2 (2011-10-23)