Smarty多语言化的简单实现

时间:2022-05-20 15:54:10

 

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文件名。