• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Switching contents language in CodeIgniter

#1
[eluser]KeyStroke[/eluser]
Hi,

I'm going to use CI's language class to make a site that supports English and Arabic. I have two questions about that though:

1) How do you usually separate both versions of the site?

for example: is it like ar.yourdomain.com/home (ar = Arabic), or yourdomain.com/ar/home? or maybe another way?




2) How do you swap languages within the application? Do you set a global language variable in each PHP file or a bunch of IF statements throughout the program or how exactly?


You help is much appreciated Smile

#2
[eluser]gon[/eluser]
Hi,

Quote:1) How do you usually separate both versions of the site?
for example: is it like ar.yourdomain.com/home (ar = Arabic), or yourdomain.com/ar/home? or maybe another way?

I use the second option.

Quote:2) How do you swap languages within the application? Do you set a global language variable in each PHP file or a bunch of IF statements throughout the program or how exactly?

One of the first things you should do in every controller is get the language from the first url segment. You should try to do this automatically. For example extending all controllers from another one that do this in the constructor. And keep the language in a global var, ie $language.

You could then use that language var in the SQL queries, or elsewhere, but there should be no IFs because all the code should be the same. Just using a different value on $language var.

For the actual translation, you can use the language library that CI provides, or just use keys in the views and doing replacements after rendering the view.
For example:

<title>__TITLE__</title>

And after getting the view, execute a function that seeks for __KEY__ in the HTML, gets the KEY name, and looks for the translation. The translation values can be taken from an array:
$i18n['TITLE']['en'] = "english title";
$i18n['TITLE']['ar'] = "arabic title";
Actually the CI language class works just this way.

regards

#3
[eluser]KeyStroke[/eluser]
Thanks a lot gon! I have two more questions if you don't mind:

1) In language files, should English and Arabic array keys be different from each other (e.g: $lang['welcome_en'] and $lang['welcome_ar'])? or are they supposed to use the same key name since they're in different files?

2) How do I use the 'yourdomain.com/ar/home' URI structure when home is my default controller? I don't know how that would work with other controllers either.


Appreciate your help Smile

#4
[eluser]gon[/eluser]
Quote:1) In language files, should English and Arabic array keys be different from each other (e.g: $lang[’welcome_en’] and $lang[’welcome_ar’])? or are they supposed to use the same key name since they’re in different files?

Using CI language files, you generate 2 files with the same name, and store them in its folder:
arabic/mytranslations.php
english/mytranslations.php

Read the user guide for details on loading the correct file.

Quote:2) How do I use the ‘yourdomain.com/ar/home’ URI structure when home is my default controller? I don’t know how that would work with other controllers either.

Sometimes I extend the CI URI library to make it work the way I want. For example, store the first uri segment in the $language var, and consider the second segment to be the first, so controllers will load as usual.

But you can try using .htaccess rules, or CI routing.

Good luck

#5
[eluser]KeyStroke[/eluser]
So you mean I should detect the language first in the URI and load the matching file in each controller?

#6
[eluser]sikkle[/eluser]
gon : is it possible for you to send me sample of what you do (extend the ci uri libs) ? private or new thread whatever Smile

#7
[eluser]gon[/eluser]
Hi, I've reviewed the code.
The class that gets extended is Router.
Also, you'll see that some configuration params must be set.

Don't have time to explain further!!!!

hope this helps.


Code:
<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');


class MY_Router extends CI_Router {
    
    var $lang;
    var $lang_uri=null;                // esto es por lo que se sustituira [lang] en las traducciones
    var $redirect_to_default=null;
        
    function _extract_lang($uri) {
                
        if (preg_match("/^\/*(\w{2})\//", $uri, $match)) {
            if (array_key_exists($match[1], $this->config->item("lang")) ) {
                $this->lang = $match[1];
                $uri = preg_replace("/^\/".$this->lang."\//", "/", $uri);
                
                // si entramos con el lenguage default indicando la cadena,
                // haremos un redirect en el controlador
                if ($this->lang == $this->config->item("default", "lang")) {
                    $this->redirect_to_default = $uri;
                    $this->lang_uri="";
                }
                else
                    $this->lang_uri = "/".$this->lang;
                
            }                
        }
        else {                        
            $this->lang = $this->config->item("default", "lang");                        
        }
        $this->config->set_item('language', $this->config->item($this->lang, "lang"));
        return $uri;
    }


    function _get_uri_string()
    {
        return $this->_extract_lang($this->_original_get_uri_string());
    }
    function _original_get_uri_string() {
    
        if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')
        {
            // If the URL has a question mark then it's simplest to just
            // build the URI string from the zero index of the $_GET array.
            // This avoids having to deal with $_SERVER variables, which
            // can be unreliable in some environments
            if (is_array($_GET) AND count($_GET) == 1)
            {
                // Note: Due to a bug in current() that affects some versions
                // of PHP we can not pass function call directly into it
                $keys = array_keys($_GET);
                return current($keys);
            }
        
            // Is there a PATH_INFO variable?
            // Note: some servers seem to have trouble with getenv() so we'll test it two ways        
            $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');            
            if ($path != '' AND $path != "/".SELF)
            {
                return $path;
            }
                    
            // No PATH_INFO?... What about QUERY_STRING?
            $path =  (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');    
            if ($path != '')
            {
                return $path;
            }
            
            // No QUERY_STRING?... Maybe the ORIG_PATH_INFO variable exists?
            $path = (isset($_SERVER['ORIG_PATH_INFO'])) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO');    
            if ($path != '' AND $path != "/".SELF)
            {
                return $path;
            }

            // We've exhausted all our options...
            return '';
        }
        else
        {
            $uri = strtoupper($this->config->item('uri_protocol'));
            
            if ($uri == 'REQUEST_URI')
            {
                return $this->_parse_request_uri();
            }
            
            return (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);
        }
    }
}

#8
[eluser]Блум[/eluser]
I found a different and IMHO a very easy and harmless way to have a language segment in your URL (http://yoursite.com/en/news/54) without changing the config options. The good thing is that you do not have to have
Code:
$config['uri_protocol']    = "ORIG_PATH_INFO";
and
Code:
$config['enable_query_strings'] = TRUE;
in your config.

All you have to do is:
1. .htacces
Code:
RewriteEngine on
RewriteCond $2 !^(index\.php|images|robots\.txt|css)
RewriteRule ^(bg|en)?(.*)$ /index.php/$2 [L]
Where 'bgen' is list of the languages that you want in the URL, In this case I want 'en' and 'bg'. This one just skips the language from the query to index.php

2. In index.php (in the root of your project) define a constant from the language query in the URL before CI spread it away.
Code:
<?php
// language constant
$urlData = explode('/',$_SERVER['REQUEST_URI']);
if (strlen($urlData[1]) == 2) define ('LANG',$urlData[1]); else define ('LANG',false);
?>

So now you can use the current LANG constant everywhere in your project, and URI Class is working the same: On url: http://yoursite.com/bg/news/42
Code:
echo 'Lang:'.LANG."; ";
echo 'Article:'.$this->uri->segment(2);
will output 'Lang:bg; Article:42'.

#9
[eluser]wiredesignz[/eluser]
Or you could use the URI Language Identifier extension. http://codeigniter.com/wiki/URI_Language_Identifier/

#10
[eluser]Блум[/eluser]
I didn't know about it, it is terrific.


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.