Smarty是一个使用PHP写出来的模板PHP模板引擎,是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与HTML 代码混杂在一起PHP 代码逻辑分离。
用过Smarty的人都知道Smarty是个好东西。做模板一定要多语言化,可是Smarty却没有实现这功能,无聊之际自己简单实现了把。
看了几个开源框架的多语言化实现方法,都是替换实现的,或许这是最好的方法吧,谁有更好的实现技术,请通知我一下,一起学习。
下面进入正题
Smarty 是通过缓存技术来实现的PHP模板引擎,通过事先把模板编译并缓存起来。对于模板编译成的php文件的命名,有自己有命名规则。具体是什么,在这就不深加讨论了,有兴趣的可以自己研究源码。要想实现多语言化,并不破坏Smarty的优越性,那么,模板编译成的php文件也应该是分多语言的。也就是说生成诸如en.php和zh.php的模板php文件。在模板编译保存之前需要采用替换技术,对模板进行多语言化,在此我选择了重写 _fetch_resource_info(在提取模板时就对其进行多语言化),同样的,需要重写Smarty的_get_compile_path以便区别是哪种语言下的模板,这也就是对模板编译后保存的php文件名进行了多语言区分。
下面是实现代码
//Template.class.php
<?php
require 'smarty/libs/Smarty.class.php';
/*
* Template extends Smarty
*/
class Template extends Smarty{
/*
* overwrite _fetch_resource_info
* add _translate_source_content
*/
function _fetch_resource_info(&$params)
{
$_return = parent::_fetch_resource_info($params);
if($_return)
$this->_translate_source_content($params['source_content']);
return $_return;
}
/*
* overwrite _get_compile_path
* add path identify by language
*/
function _get_compile_path($resource_name)
{
if(!isset($GLOBALS['language']))
$this->_set_Locale_language();
return parent::_get_auto_filename($this->compile_dir, $resource_name,
$this->_compile_id) .'.'.$GLOBALS['language']. '.php';
}
/*
* set the language,get from browser
*/
function _set_Locale_language(){
preg_match('/^([a-z/-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
$GLOBALS['language'] = $matches[1];
if($GLOBALS['language'] == '')
$GLOBALS['language'] = 'en';
}
/*
* translate the template
*/
function _translate_source_content(&$source_content){
$dir = 'languages';
if(!isset($GLOBALS['language']))
$this->_set_Locale_language();
$language = $GLOBALS['language'];
if(!is_file($dir.'/'.$language.'.php'))
$language = 'en';
$languageFile = $dir.'/'.$language.'.php';
if (is_file($languageFile) && include ($languageFile))
$source_content = preg_replace('///[//#([^//]//[]+)]/Usie',"///$GLOBALS[///$language]['//1' ]", $source_content);
}
}
?>
在此之前还要把相关的多语言化内容加载进来。
定义一个加载言语的方法。在些直接放到言语文件中了。
//en.php
<?php
$english = array(
//global
"hello" => "你好",
"world" => "Smarty",
);
add_translation("zh",$english);
function add_translation($country_code, $language_array) {
$country_code = strtolower($country_code);
$country_code = trim($country_code);
if (is_array($language_array) && sizeof($language_array) > 0 && $country_code != "") {
if (!isset($GLOBALS[$country_code])) {
$GLOBALS[$country_code] = $language_array;
} else {
$GLOBALS[$country_code] = array_merge($GLOBALS[$country_code],$language_array);
}
return true;
}
return false;
}
?>
现在只要在模板中定义如 [#hello] [#world] 并把相应的翻译内容加入对应的语言文件中就可以了。
到些Smarty多语言化实现结束。
总结:
1.定义翻译内容的语言文件
2.定义加载翻译内容的方法 add_translation
3.定义获取言语的方法 _set_Locale_language
3.定义获翻译的方法 _translate_source_content
4.重载_fetch_resource_info对模板进行翻译
5.重载_get_compile_path按多言语化的要求生成编译后的模板php文件名。