[yii] gestion des langues dans les urls
Yii permet comme la plupart des frameworks de gérer les langues différentes dans un site.
Nous allons voir comment mettre ça en place.
Commençons par créer une table avec la commande SQL suivante :
CREATE TABLE `t_lang` ( `lang_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 (`lang_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Et nous y ajoutons deux langues, dont l’anglais par défaut.
INSERT INTO `t_lang` VALUES(1, 'English', 'en', '/img/lang/en.jpg', 1, 1); INSERT INTO `t_lang` VALUES(2, 'Francais', 'fr', '/img/lang/fr.jpg', 1, 0);
Nous allons créer le model « t_lang.php » dans le répertoire « models ».
<?php /** * This is the model class for table "t_lang". * * The followings are the available columns in table 't_lang': * @property integer $id * @property string $name * @property string $lang * @property string $flagpath * @property integer $active * @property integer $main */ class t_lang extends CActiveRecord { /** * Returns the static model of the specified AR class. * @return t_lang the static model class */ public static function model($className=__CLASS__) { return parent::model($className); } /** * @return string the associated database table name */ public function tableName() { return 't_lang'; } /** * @return array validation rules for model attributes. */ public function rules() { // NOTE: you should only define rules for those attributes that // will receive user inputs. return array( array('name, lang, flagpath, active, main', 'required'), array('active, main', 'numerical', 'integerOnly'=>true), array('name', 'length', 'max'=>20), array('lang', 'length', 'max'=>2), array('flagpath', 'length', 'max'=>40), // The following rule is used by search(). // Please remove those attributes that should not be searched. array('id, name, lang, flagpath, active, main', 'safe', 'on'=>'search'), ); } /** * @return array relational rules. */ public function relations() { // NOTE: you may need to adjust the relation name and the related // class name for the relations automatically generated below. return array( ); } /** * @return array customized attribute labels (name=>label) */ public function attributeLabels() { return array( 'id' => 'Id', 'name' => 'Name', 'lang' => 'Lang', 'flagpath' => 'Flagpath', 'active' => 'Active', 'main' => 'Main', ); } /** * Retrieves a list of models based on the current search/filter conditions. * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions. */ public function search() { // Warning: Please modify the following code to remove attributes that // should not be searched. $criteria=new CDbCriteria; $criteria->compare('id',$this->id); $criteria->compare('name',$this->name,true); $criteria->compare('lang',$this->lang,true); $criteria->compare('flagpath',$this->flagpath,true); $criteria->compare('active',$this->active); $criteria->compare('main',$this->main); return new CActiveDataProvider('t_lang', array( 'criteria'=>$criteria, )); } }
Maintenant que les éléments de base de données sont en place, nous allons créer le composant « Lang.php » dans le répertoire « components » :
<?php class Lang extends CActiveRecord{ public static function model($className = __CLASS__) { return parent::model($className); } public function tableName() { return "t_lang"; } 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; } }
Et maintenant le composant « UrlManager.php » aussi dans le répertoire « components » :
<?php class UrlManager extends CUrlManager{ public function createUrl($route, $params = array(), $ampersand = '&') { if(empty($params['lang'])){ $params['lang'] = self::processUrl(); } return parent::createUrl($route, $params, $ampersand); } public static function processUrl(){ if(isset( $_GET['lang'] )){ Yii::app()->setLanguage( $_GET['lang'] ); } else { Yii::app()->setLanguage(Lang::getdefaultLanguage()); } if(isset($_GET['lang'])){ return Lang::findByCode(Yii::app()->language, Yii::app()->controller->route); }else{ return Lang::findByCode(Lang::getdefaultLanguage(), Yii::app()->controller->route); } } }
Faisons appel à ce dernier composant dans un controlleur d’exemple « SiteController.php » :
<?php class SiteController extends Controller { // (...) protected function beforeAction($action) { UrlManager::processUrl(); return parent::beforeAction($action); } }
Il nous reste à activer cela dans la config « main.php » :
<?php return array( 'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..', 'name'=>'comecooking', 'runtimePath' => $runtimePath, 'sourceLanguage' => 'en', // (...) 'urlManager'=>array( 'urlFormat'=>'path', 'class'=>'UrlManager', 'showScriptName'=>false, 'rules'=>array( '<lang>/'=>'site/index', '<lang>/<controller:\w+>'=>'<controller>/index', '<lang>/<controller:\w+>/<action:\w+>'=>'<controller>/<action>', '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>', '<lang>/<controller:\w+>/<action:\w+>/<view:\w+>'=>'<controller>/<view>/<page>', '<lang>'=>'/', ), ), // (...) );
Et voilà un site multilangue.
La source en anglais de cet article (avec quelques adaptations de ma part) :
http://www.yiiframework.com/wiki/210/multilanguage-web-site-controlling-by-get-request-and-database-allowed-languages/
1 réponse
[…] Il faut néanmoins avoir mis en place une gestion des langues et un rewrite url comme vu dans l’article http://codus.acyclique.com/yii-gestion-des-langues-dans-les-urls/ […]