Multilanguage web site controlling by get request and database allowed languages

You are viewing revision #7 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version.

next (#8) »

  1. You can controll your languages in admin
  2. 1.init()
  3. 2.processUrl()
  4. 3.beforeAction()
  5. UrlMAnager
  6. Configure ROUTES
  7. Language routes

You can controll your languages in admin ¶

First You have to have create database table for default language and allowed languages.

CREATE TABLE IF NOT EXISTS `tbl_languages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `lang` varchar(2) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `flagpath` varchar(40) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `active` tinyint(1) NOT NULL,
  `main` tinyint(1) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;

INSERT INTO `tbl_languages` (`id`, `name`, `lang`, `flagpath`, `active`, `main`) VALUES
(1, 'English', 'en', '/img/lang/en.jpg', 1, 1),
(2, 'Croatian', 'hr', '/img/lang/hr.jpg', 1, 0);

After Table you have to make model for use:

class Lang extends CActiveRecord{
    
        /*
     * This method is used for static model calls
    */
    public static function model($className = __CLASS__) {
        return parent::model($className);
    }
    
    public function tableName() {
        return "tbl_languages";
    }
    
    /*
     * Function For check lang by get request eq /hr/site/index
     * If language is by get request found in database and active langage will return current link eg /hr/site/active if your request is eg /fr/site/index
     * in this case will return /en/site/index while fr langage is not in database
     * @param cod varchar 2
     * @param route current action route 
     * @param redirection default to true to redirect from eg /fr/ to /en/ while fr dont exists as language 
     */
    public static function findByCode($cod,$route,$redirect = true){
        $cod = substr($cod,0,2);
        $data = self::model()->find('lang=:LANG AND active = 1',array(':LANG'=>$cod));
        if(empty($data)){
            $lang = self::getdefaultLanguage();
          
            if($redirect == true){
                if(preg_match("/index/", $route))
                Yii::app()->controller->redirect(Yii::app()->homeUrl.$lang.'/');        
                else        
                Yii::app()->controller->redirect(Yii::app()->homeUrl.$lang.'/'.$route);
            }else
            return $lang;    
        } 
        else
        return $data->lang;
    }
    
    /*
     * get default language
     */
    public static function getdefaultLanguage(){
        return self::model()->find('main = 1')->lang;
    }
    
  
}   

Now we have to make Some Functions in component Controller witch extends CController

1.init() ¶

On every Controller instance set the language

2.processUrl() ¶

Find the language and set current route

3.beforeAction() ¶

Do that before each action.

class Controller extends CController{
        
        /*
         * On every Controller instance set language from get if is index page get main language
         */
        public function init(){
            if(isset($_GET['lang']))
                Yii::app()->setLanguage($_GET['lang']);
            else
                Yii::app()->setLanguage(Lang::getdefaultLanguage());
            parent::init();
        }

       /*
         * ProcesUrl method used for resolving languages if dont have get language
         * System gets default language defined from database
         */
        public static function processUrl(){

                if(isset($_GET['lang'])){
                    return Lang::findByCode(Yii::app()->language,  Yii::app()->controller->route);
                }else{ 
                    return Lang::findByCode(Lang::getdefaultLanguage(),  Yii::app()->controller->route);   
                }
        }
        
         /*
         * Aftereach action processUrl
         */
         protected function beforeAction($action) {
            self::processUrl();
            return parent::beforeAction($action);
        }


}

UrlMAnager ¶

And final make the UrlMAnager class to component folder for rewrite current createUrl for each call add automatic lang to url

class UrlManager extends CUrlManager{
    
    /*
    * rewriten behavior
    */
    public function createUrl($route, $params = array(), $ampersand = '&') {
        $params['lang'] = Controller::processUrl();
        return parent::createUrl($route, $params, $ampersand);
    }
    
    
}

Configure ROUTES ¶

Add it to main.php

Language routes ¶

1. rule is default ¶
2. rule is for /hr/admin remove index from controller ¶
3. rule is for each controler action /en/site/index ¶
4. rule is for redirecting /en/ for redirecting index to language /de/ /fr/ ¶

depends on database

'urlManager'=>array(
'class'=>'UrlManager',    
'urlFormat'=>'path',
'rules'=>array(    
'/'=>'site/index',      
'<lang>/<controller:\w+>'=>'<controller>/index', 
'<lang>/<controller:\w+>/<action:\w+>'=>'<controller>/<action>',   
'<lang>'=>'/',          
),
'showScriptName'=>false,
);