Yii Framework结合Theme、Language和Module

很长时间都在使用Yii做SNS游戏后台,其类导入、全局变量生命、对象自动实例化、Behavior、Event都十分好用。

最近研究了一下其WEB方面都东西,主要从Theme、Language、Module方面入手。

通常一个Yii的app目录结构如下:
[quote]
app
----assets
----images
----css
----protected
--------commands
--------components
--------config
--------controllers
--------extensions
--------models
--------modules
--------views
----themes
--------classic
------------views
----------------layout
----------------system
----------------site
[/quote]
Theme是Yii系统支持的。当设置了Yii::app()->theme="xxxx"的时候,app根目录下的themes中的相应的theme就会起作用。比如设置Yii::app()->theme="classic",那么themes/classic/views就会替代protected/views作为视图资源存放的地方,除非视图文件不存在,才会启用protected/views下的视图文件。

Yii内置了翻译器,可以使用Yii::t()来进行翻译,这个可以通过Yii::app()->language来控制目标语言。

Module是一个模块,包含了controller、model、view。

在原生的Yii系统里是支持Theme和Module结合。比如系统里建立一个Module名字为test,在protected/modules下结构如下:
[quote]
protected
----modules
--------test
------------components
------------controllers
------------models
------------views
----------------default
----------------layouts
------------TestModule.php
[/quote]
这个时候设置了Yii::app()->theme="classic",就可以将protected/modules/test/views复制到themes/classic/views/下,并起名为test。
但是如果要再结合language做i18n支持,就不是那么容易了。首先将i18n相关语言使用Yii::t()来翻译,本身是一个效率低下的事情;其次,因为语言不同,势必会影响到界面排版,所以用一个view文件来控制就显得捉襟见肘。

解决的思路是在controller解析view文件路径的时候,加上language标识。优先级是先找themes下带language的路经,如果没有则找themes下不带language的路径,如果没有则找modules下的views的带language的路径,如果没有则找modules下的views的不带language的路径。

我的做法如下:

1、修改CController.php

public function resolveViewFile($viewName,$viewPath,$basePath,$moduleViewPath=null)
{
if(empty($viewName))
return false;

if($moduleViewPath===null)
$moduleViewPath=$basePath;

if(($renderer=Yii::app()->getViewRenderer())!==null)
$extension=$renderer->fileExtension;
else
$extension='.php';
if($viewName[0]==='/')
{
if(strncmp($viewName,'//',2)===0)
$viewFile=$basePath.$viewName;
else
$viewFile=$moduleViewPath.$viewName;
}
else if(strpos($viewName,'.'))
$viewFile=Yii::getPathOfAlias($viewName);
else {
$viewFileBak = $viewFile=$viewPath.DIRECTORY_SEPARATOR.$viewName;
if (isset(Yii::app()->language)) {
$viewFile=$viewPath.DIRECTORY_SEPARATOR.Yii::app()->language.DIRECTORY_SEPARATOR.$viewName;
}
}

if(is_file($viewFile.$extension))
return Yii::app()->findLocalizedFile($viewFile.$extension);
else if($extension!=='.php' && is_file($viewFile.'.php'))
return Yii::app()->findLocalizedFile($viewFile.'.php');
else {
if (isset($viewFileBak)) {
if(is_file($viewFileBak.$extension))
return Yii::app()->findLocalizedFile($viewFileBak.$extension);
else if($extension!=='.php' && is_file($viewFileBak.'.php'))
return Yii::app()->findLocalizedFile($viewFileBak.'.php');
}
}
return false;
}


2、在protected/components里新增TLController.php

/**
* Abstract controller class for Theme&Language Controller.<br>
* @author henry
*
*/
abstract class TLController extends CController {
/**
* @var array context menu items. This property will be assigned to {@link CMenu::items}.
*/
public $menu=array();
/**
* @var array the breadcrumbs of the current page. The value of this property will
* be assigned to {@link CBreadcrumbs::links}. Please refer to {@link CBreadcrumbs::links}
* for more details on how to specify this property.
*/
public $breadcrumbs=array();


public function init() {
parent::init();

if ($this->hasEventhandler('onControllerInit')) {
$this->onControllerInit(new CEvent($this));
}

//$this->layout = '/layouts/'.Yii::app()->language.'/column1';
}
/**
* Supported befaviors
* @return array
*/
public function behaviors() {
return array_merge(parent::behaviors(), array(
'themeBehavior'=>array(
'class'=>'application.behaviors.ThemeBehavior',
),
'langBehavior'=>array(
'class'=>'application.behaviors.LangBehavior',
),
));
}

public function onControllerInit($event) {
$this->raiseEvent('onControllerInit', $event);
}
}


3、在protected/behaviors增加2个Behavior:

//ThemeBehavior.php
class ThemeBehavior extends CBehavior {
const COOKIE_KEY = '__theme';

public function events() {
return array_merge(parent::events(), array(
'onControllerInit'=>'controllerInit',
));
}


public function controllerInit($event) {
$v = Yii::app()->request->getParam(self::COOKIE_KEY);
if (!isset($v)) {
$v = Yii::app()->request->cookies[self::COOKIE_KEY];
if (!isset($v)) {
$v = Yii::app()->theme->name;
} else {
$v = $v->value;
}
}
Yii::app()->theme = $v;
Yii::app()->request->cookies[self::COOKIE_KEY] = new CHttpCookie(self::COOKIE_KEY, $v);
}
}


//LangBehavior.php
class LangBehavior extends CBehavior {
const COOKIE_KEY = '__lang';

private $_lang = '';

public function events() {
return array_merge(parent::events(), array(
'onControllerInit'=>'controllerInit',
));
}


public function controllerInit($event) {
$v = Yii::app()->request->getParam(self::COOKIE_KEY);
if (!isset($v)) {
$v = Yii::app()->request->cookies[self::COOKIE_KEY];
if (!isset($v)) {
$v = Yii::app()->language;
} else {
$v = $v->value;
}
}
Yii::app()->language = $v;
Yii::app()->request->cookies[self::COOKIE_KEY] = new CHttpCookie(self::COOKIE_KEY, $v);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值