ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

URI Language Identifier

April 09, 2008 11:45pm

Subscribe [14]
  • #1 / Apr 09, 2008 11:45pm

    wiredesignz

    2882 posts

    This language class extension allows you to automatically prefix all site urls with a language abbreviation that is pre-defined in your config file or from a link and automatically load the corresponding language translation file, the route will then be corrected by the route regex for everything to work as normal.

    Somewhere in the site you can provide the user with links allowing them to change their desired language name.
    http://domain.tld/en/controller/method
    http://domain.tld/es/controller/method
    http://domain.tld/de/controller/method

    Now available on the wiki: http://codeigniter.com/wiki/URI_Language_Identifier/

    As usual, your comments and ideas are appreciated.

  • #2 / Apr 10, 2008 12:09am

    wiredesignz

    2882 posts

    If anyone has ideas on the best method to dymanically change the language prefix for a user, it would be greatly appreciated. Maybe using Session or a Cookie?

    The only value that needs storing is their config language name.

    Update #1 - Cookie is used to store user selected language.

  • #3 / Apr 10, 2008 2:40am

    barbazul

    99 posts

    I haven’t actually tried that code but, for what I can see, there is no need for the cookie as the language preference will always propagate through the URL.

    I can see how the cookie can help saving the user preference for future visits but IMHO its better to leave that choice in the hands of each particular developer tastes.

    Another remark, and this is almost trivial, but when using this extension you cannot have a controller name that is exactly 2 characters long :p

  • #4 / Apr 10, 2008 3:14am

    wiredesignz

    2882 posts

    A new visitor may wish to change their language preference from the default so the cookie is required.

    I haven’t fully tested the routing so it will probably need adjusting to suit each application.

    And, Yes, of course a developer could deliberately name a controller which causes the regex (and his application) to fail.

  • #5 / Apr 10, 2008 10:20am

    barbazul

    99 posts

    A new visitor may wish to change their language preference from the default so the cookie is required.

    I haven’t fully tested the routing so it will probably need adjusting to suit each application.

    And, Yes, of course a developer could deliberately name a controller which causes the regex (and his application) to fail.

    Not really.

    Think of this: a new visitor navigates to http://www.domain.com/welcome/index which is, by default displayed in english.
    since he is a native spanish speaker he clicks on a small icon with the spanish flag which links to http://www.domain.com/es/welcome/index from that point on all links will have the /es/ appended to them.

    Of course when he visits the site again he would have lost the desired language preference, but on some cases this might be de desired functionality, that’s my point of view

  • #6 / Apr 10, 2008 11:14am

    wiredesignz

    2882 posts

    Ok, I see what you mean now, that is even easier because the uri->segement(1) contains the language abbreviation.

    Update #2 Change from cookie to uri->segment. Thanks barbazul 😉

    EDIT: The script may die if an unknown abbreviation is in the URL, will fix this soon.

  • #7 / Apr 10, 2008 11:26am

    barbazul

    99 posts

    Hey!

    I thank YOU for giving me something to keep my PHP-CI skills sharp now that I’m unenployed and also thank you for developing cool code while you’re at it! :D

  • #8 / Apr 10, 2008 11:43am

    wiredesignz

    2882 posts

    Man that works great, I have just tested using two language files and Modular Extensions and it’s all good. Thanks barbazul. 😉

    However an unknown abbreviation will generate an error, but it still loads the default language and continues. So a simple @ will fix that pesky error for now.

    If anyone has more ideas please step up.

  • #9 / Apr 10, 2008 12:14pm

    wiredesignz

    2882 posts

    Update #3 Added detection for missing or invalid uri segment.

  • #10 / Apr 10, 2008 12:34pm

    Pascal Kriete

    2589 posts

    For larger projects I like to split up my language files and load them when necessary, so support for that would be nice.  Easy change:
    1. Add class var for current language
    2. Override load to use that language

  • #11 / Apr 10, 2008 12:38pm

    wiredesignz

    2882 posts

    Inparo, could you show me some code describing you idea please.

  • #12 / Apr 10, 2008 1:05pm

    Pascal Kriete

    2589 posts

    Damn, I thought I could get away with being lazy 😛.

    Fictional Situation:
    Language definitions for shared data is stored in APPPATH/language/current_lang/current_lang.php
    Language definitions for my frontend are stored in APPPATH/language/current_lang/frontend.php
    Language definitions for my backend are stored in APPPATH/language/current_lang/backend.php

    They’re separated like that for clarity.

    I this situation I would probably autoload the language library, so the first language file is loaded in your constructor.

    In my frontend controller I would normally do:

    $this->lang->load('frontend', current_lang);

    But the constructor already grabbed the language so why should I do it again.
    There are two solutions that I can think of. The first is an accessor method that returns the current language, so my call becomes:

    $this->lang->load('frontend' $this->lang->get_lang() );

    Or the other solution is overriding the load function to allow for this:

    $this->lang->load('frontend');

    The second solution makes more sense to me.  Something like this should do it:

    class MY_Language extends CI_Language
    {
        // ADDED THIS
        var $lang;
    
        function MY_Language()
        {
            parent::CI_Language();
            
            global $RTR;
            
            //get the language from uri segment
            $lang_abbr = $RTR->uri->segment(1);
            $lang_uri_abbr = $RTR->config->item('lang_uri_abbr');        
    
            //or from the config language
            if(!isset($lang_uri_abbr[$lang_abbr]))
            {
                $user_lang = $RTR->config->item('language');
                $lang_abbr = $RTR->config->item('language_abbr');
            }
            else
                $user_lang = $lang_uri_abbr[$lang_abbr];
    
            // AND THIS
            $this->lang = $user_lang;
    
            //....
        }
    
        function load($langfile)
        {
            parent::load($langfile, $this->lang);
        }
    }
  • #13 / Apr 10, 2008 1:36pm

    Tony Nash

    42 posts

    Great stuff!.. Few months ago I came across with a similar requirement for one of my client project. However, due to the complexity of the project and CI lost feature of partials (blocks) rendering, I could not use CI for that project (sham on me). But I hope my project requirements could help you to build this extension better.

    Default language was: http://domain.tld/en/controller/method = http://domain.tld/controller/method

    A) Site check for a cookie and see if the user has already set the default language. If not
    B) The site detect the language type from the user browser agent
    C) If the browser unable to supply this information (this is true on some mobile browsers), it use the default language in the config file.
    D) This will be saved in a cookie for future reference
    E) All site functions (in CI, it will be the controllers) will then refer to the user cookie or current php session to detect the language type and work accordingly.

    Pretty simple ahaa.. 😉

    EDIT: BTW: I did not test your code or go through it thoroughly..

  • #14 / Apr 10, 2008 2:40pm

    barbazul

    99 posts

    @inparo: your suggestion is automatically supported with no further changes to either the core or wiredesignz’s extension.
    Look at the Language::load implementation on line 61 of system/libraries/Language.php:

    function load($langfile = '', $idiom = '', $return = FALSE)
    
    {    
    
    
    ...some code…
            
    
    if ($idiom == '')
    
    {
    
        $CI =& get_instance();
    
        $deft_lang = $CI->config->item('language');
    
        $idiom = ($deft_lang == '') ? 'english' : $deft_lang;
    
    }
    
    ...more code…
    
    }

    The language lib checks for the config variable “language” which is overriden by wiredesignz’s extension

  • #15 / Apr 10, 2008 2:56pm

    Pascal Kriete

    2589 posts

    Oh my, that’s what happens when you don’t test.  Thanks for catching that.  /me feels stupid.

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases