2011-06-09 106 views
5

我有兩個模塊(管理和公共)和Zend公司申請公開我有以下的插件來分析我的友好,網址:Zend框架中正確使用語言

class Custom_Controller_Plugin_Initializer extends Zend_Controller_Plugin_Abstract { 

    protected $_front; 
    protected $_request; 

    public function __construct() { 
     $this->_front = Zend_Controller_Front::getInstance(); 
     $this->_request = $this->_front->getRequest();   
    } 

    public function preDispatch(Zend_Controller_Request_Abstract $request) { 
    //checking if the url ends with "/"  
     $requestUri = $this->_request->getRequestUri(); 
     $path = parse_url($requestUri, PHP_URL_PATH); 
     $query = parse_url($requestUri, PHP_URL_QUERY); 
     if (substr($path, -1) != '/') { 
      header('location: ' . $path . (isset($query) ? '/?' . $query : '/')); 
      die(); 
     } 
// exploding the uri to get the parts.   
     $uri = explode('/', substr($path, strlen(Zend_Controller_Front::getInstance()->getBaseUrl()) + 1)); 


     $modelLanguage = new Model_Db_Language(); 
    //checking if the first part is of 2 characters and if it's a registered language 
     if ($modelLanguage->checkLanguage($uri[0])) {    
      $language = $uri[0]; 
      unset($uri[0]); //deleting the language from the uri. 
      $uri = array_values($uri); 
     } else { 
      $language = $modelLanguage->autoLanguage(); 
      if (!$uri[0] == '' && (strlen($uri[0]) == 2)) { 
       $uri[0] = $language; 
       header('location: ' . Zend_Controller_Front::getInstance()->getBaseUrl() . '/' . implode($uri) . (isset($query) ? '/?' . $query : '/')); 
       die(); 
      } 
     } 

//remember that the language was deleted from the uri 
     $this->_request->setParam('requestUri', implode('/', $uri)); 

     switch ($uri[0]) { 
      case 'search': 
       unset($uri[0]); 
       $this->_request->setParam('s', urldecode($uri[2])); 
       $this->_request->setModuleName('public'); 
       $this->_request->setControllerName('content'); 
       $this->_request->setActionName('search'); 
       $this->_request->setParam('template', 'search'); 
       break; 
     } 
     $this->_initTranslation($language); 
      $this->_initInterface(); 
}} 

這是,如果非常有用我想使用像domain.com/en/about-us/mision/這樣的結構,因爲我可以解析url並獲得第一個參數「en」,之後找到與「about-us/mission」關聯的頁面,但如果我想使用domain.com/en/user/profile/id/1/,Zend設置「en 「作爲控制器和」用戶「作爲動作。我怎樣才能在URL中正確設置語言?

回答

9

這是一個常見問題,所以讓我進行一般化和形式化。

比方說,你希望你的web應用程序支持多國語言,你有以下路由要求:

http://domain.com/language-code/controller-name/action-name

換句話說,你要使用的「語言代碼」的語言環境和結合前面使用默認的Zend模塊路由。

假設您還想使用Zend_Translate根據語言環境提供翻譯的內容。

下面是我使用的一些代碼,並經常「導出」到具有類似要求的項目中,我打算進一步討論。

相關配置項:

resources.frontController.plugins.Language = Plugin_Language 
resources.frontController.actionHelperPaths.Controller_Helper = APPLICATION_PATH "/controllers/helpers" 


; Locale 

resources.locale.default = "en_US" 
resources.locale.force = false 

; Translate 

resources.translate.adapter = "Csv" 
resources.translate.data = APPLICATION_PATH "/languages" 

resources.translate.locale = "auto" 
resources.translate.disableNotices = true 
resources.translate.scan = directory 



; Routes 

resources.router.routes.module.type = Zend_Controller_Router_Route_Module 
resources.router.routes.module.abstract = On  

resources.router.routes.language.type = Zend_Controller_Router_Route 
resources.router.routes.language.route = ":language" 
resources.router.routes.language.reqs.language = "^[a-z]{2}$" 
resources.router.routes.language.defaults.language = "en" 

resources.router.routes.default.type = Zend_Controller_Router_Route_Chain 
resources.router.routes.default.chain = "language,module" 


; View 

resources.view.helperPath.View_Helper = APPLICATION_PATH "/views/helpers" 

這裏註冊的插件語言:

class Plugin_Language extends Zend_Controller_Plugin_Abstract { 

    public function routeStartup(Zend_Controller_Request_Abstract $request){ 

     if (substr($request->getRequestUri(), 0, -1) == $request->getBaseUrl()){ 

      /* Access to the Base Url (no language information) */ 

      /* Get current locale language (autodetected) */ 
      $language = Zend_Registry::get("Zend_Locale")->getLanguage(); 


      /* If requested language isn't available set to the default one */ 
      if (!Zend_Registry::get('Zend_Translate')->isAvailable($language)){ 

       Zend_Registry::set(
        "Zend_Locale", 
        new Zend_Locale("default") 
       ); 

       $language = Zend_Registry::get("Zend_Locale")->getLanguage(); 

       Zend_Registry::get("Zend_Translate")->setLocale(
        Zend_Registry::get('Zend_Locale') 
       ); 
      } 


      /* Modifiy Request Uri with Language info from current Locale */ 
      $request->setRequestUri($request->getRequestUri().$language."/"); 
      $request->setParam("language", $language); 

     } 
    } 


    public function routeShutdown(Zend_Controller_Request_Abstract $request){ 

     /* Get language from request param */ 
     $language = $request->getParam("language"); 

     /* If requested language isn't available set to the default one */ 
     if (!Zend_Registry::get('Zend_Translate')->isAvailable($language)) 
      throw new Zend_Controller_Router_Exception('Translation language is not available', 404); 

     /* Set the locale */ 

     Zend_Registry::set(
       "Zend_Locale", 
       new Zend_Locale($language) 
     ); 

     /* Set the traslator */ 

     Zend_Registry::get("Zend_Translate")->setLocale(
       Zend_Registry::get("Zend_Locale") 
     ); 


    } 

} 

動作助手:

class Controller_Helper_Language extends Zend_Controller_Action_Helper_Abstract { 

    /** 
    * 
    * Get Current language 
    * 
    * @return mixed string|null 
    */ 
    public function getCurrent(){ 

     if (!Zend_Registry::isRegistered("Zend_Locale")) 
      return null; 

     return Zend_Registry::get("Zend_Locale")->getLanguage(); 

    } 

    /** 
    * 
    * Get translator 
    * 
    * @return mixed Zend_Translate|null 
    * 
    */ 
    public function getTranslator(){ 

     if (!Zend_Registry::isRegistered("Zend_Translate")) 
      return null; 

     return Zend_Registry::get("Zend_Translate"); 

    } 

} 

視圖網址助手(覆蓋默認的)。你必須相應地使用你正在使用的新路由編寫你的網址:

class View_Helper_Url extends Zend_View_Helper_Url { 

    protected function _getCurrentLanguage(){ 

     return Zend_Controller_Action_HelperBroker::getStaticHelper('Language') 
      ->getCurrent(); 

    } 

    public function Url($urlOptions = array(), $name = null, $reset = true, $encode = true){ 

     $urlOptions = array_merge(
      array(
       "language" => $this->_getCurrentLanguage() 
      ), 
      $urlOptions 
     ); 

     return parent::url($urlOptions,$name,$reset,$encode); 

    } 

} 

希望得到這個幫助。

0

我想說你應該使用自定義路由器。這是路由器的用途 - 從URI確定參數。現在你只需讓路由器無故地工作。因爲你然後改變它的工作結果。

編寫自定義路由器並不困難,我建議你應該這樣做。你可以在裏面寫類似:

  1. 通過/
  2. 爆炸是第一部分 「恩」, 「德」 或 「ES」,如果是這樣設置LANG = $改編[0]
  3. 工作作爲默認Zend_Router的路線

而且您可以添加更多選項。也可以更快地匹配,因爲您可以邏輯地構造URI分解。正常路由器是愚蠢的 - 它只是匹配URI來路由正則表達式,並在找到匹配時停止。