2011-12-02 195 views
3

我需要一個良好的語言工作示例並在ZF內進行翻譯。ZF語言和翻譯

我的需求如下: 如果沒有選擇lang,'en'應該是默認值。 (在頁面頂部有一個lang選擇器。) lang應該存儲在會話中。 翻譯應該通過csv文件完成。 我想在URL中使語言不可見,所以如果可能的話,我不需要重新配置路由。

我發現了一些教程,但他們沒有真正的工作對我來說...

任何幫助將不勝感激... 問候 安德烈

回答

2

我用這樣的方式與使用數組,而不是CSV :

應用/ CONFIGS /的application.ini

; plugins stuff 
pluginPaths.Zle_Application_Resource = "Zle/Application/Resource" 

; locale stuff 
resources.locale.default = "it_IT" 

; cachemanager settings TODO change cache adapter to memcache 
resources.cachemanager.translator.frontend.name = Core 
resources.cachemanager.translator.frontend.customFrontendNaming = false 
resources.cachemanager.translator.frontend.options.lifetime = 7200 
resources.cachemanager.translator.frontend.options.automatic_serialization = true 
resources.cachemanager.translator.backend.name = File 
resources.cachemanager.translator.backend.customBackendNaming = false 
resources.cachemanager.translator.backend.options.cache_dir = APPLICATION_PATH "/../data/cache" 
resources.cachemanager.translator.frontendBackendAutoload = false 

; translation stuff 
resources.translate.data = APPLICATION_PATH "/../data/locales" 
resources.translate.options.disableNotices = 1 
resources.translate.options.scan = 'directory' 
resources.translate.log.stream.writerName = "Stream" 
resources.translate.log.stream.writerParams.stream = APPLICATION_PATH "/../data/logs/untranslated.log" 
resources.translate.log.stream.writerParams.mode = "a" 
resources.translate.cacheEnabled = true 

; view stuff 
resources.view.encoding = "UTF-8" 
resources.view.helperPath.My_View_Helper = "My/View/Helper" 

應用/插件/ Language.php

class Plugin_Language extends Zend_Controller_Plugin_Abstract 
{ 
    /** 
    * @var string session namespace 
    */ 
    const SESSION_NS = 'Plugin_Language'; 

    /** 
    * @var string default language for other users 
    */ 
    const DEFAULT_LOCALE = 'it'; 

    /** 
    * Called before Zend_Controller_Front enters its dispatch loop. 
    * 
    * @param Zend_Controller_Request_Abstract $request 
    * @return void 
    */ 
    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request) 
    { 
     $session = new Zend_Session_Namespace(self::SESSION_NS); 
     if (isset($session->language) && Zend_Locale::isLocale($session->language)) { 
      // change locale for the application 
      $locale = new Zend_Locale($session->language); 
      Zend_Registry::set(
       Zend_Application_Resource_Locale::DEFAULT_REGISTRY_KEY, 
       $locale 
      ); 
      // change language for the translator 
      Zend_Registry::get('Zend_Translate')->setLocale($locale); 
     } else { 
      /** @var $locale Zend_Locale */ 
      $locale = Zend_Registry::get('Zend_Locale'); 
      /** @var $translate Zend_Translate */ 
      $translate = Zend_Registry::get('Zend_Translate'); 
      // check if user language is translated 
      if (!in_array($locale->getLanguage(), $translate->getList())) { 
       // change language for the translator 
       $translate->setLocale(self::DEFAULT_LOCALE); 
      } 
     } 
    } 
} 

應用/ Bootrasp.php

protected function _initAutoload() 
{ 
    $autoloader = new Zend_Application_Module_Autoloader(array('namespace' => '', 'basePath' => APPLICATION_PATH)); 
    $autoloader->addResourceType('plugin', 'plugins', 'Plugin'); 
    return $autoloader; 
} 

應用/控制器/ LocaleController.php

class LocaleController extends Zend_Controller_Action 
{ 
    /** 
    * @var Zend_Session_Namespace 
    */ 
    protected $session; 

    public function init() 
    { 
     $this->session = new Zend_Session_Namespace(
      Plugin_Language::SESSION_NS 
     ); 
    } 

    public function itAction() 
    { 
     $this->session->language = 'it_IT'; 
     $this->_redirect($_SERVER['HTTP_REFERER']); 
    } 

    public function enAction() 
    { 
     $this->session->language = 'en_US'; 
     $this->_redirect($_SERVER['HTTP_REFERER']); 

    } 
} 

庫/我的/應用/資源/翻譯.php

class My_Application_Resource_Translate extends Zend_Application_Resource_Translate 
{ 

    /** 
    * Default key for cache manager 
    */ 
    const DEFAULT_CACHE_KEY = 'translator'; 

    /** 
    * Build a log object used internally by parent class 
    * 
    * @return void 
    */ 
    protected function buildLog() 
    { 
     if (isset($this->_options['log'])) { 
      if (is_array($this->_options['log'])) { 
       $this->_options['log'] = Zend_Log::factory($this->_options['log']); 
      } else { 
       unset($this->_options['log']); 
      } 
     } 
    } 

    /** 
    * Return string used for cache manager 
    * 
    * @return string the key used for cache manager 
    */ 
    protected function getCacheKey() 
    { 
     return isset($this->_options['cacheKey']) 
       ? $this->_options['cacheKey'] 
       : self::DEFAULT_CACHE_KEY; 
    } 

    /** 
    * Retrieve translate object 
    * 
    * @throws Zend_Application_Resource_Exception if registry key was used 
    *   already but is no instance of Zend_Translate 
    * @return Zend_Translate 
    */ 
    public function getTranslate() 
    { 
     if (null === $this->_translate) { 
      $this->buildLog(); 
      // retrieve cache if requested 
      if (isset($this->_options['cacheEnabled']) 
       && $this->_options['cacheEnabled'] 
      ) { 
       // check for cachemanager in bootstrap 
       if (!$this->getBootstrap()->hasPluginResource('cachemanager')) { 
        throw new Zend_Application_Resource_Exception(
         "You must configure the cachemanager with " 
         . "the key {$this->getCacheKey()}" 
        ); 
       } 
       // bootstrap the cachemanager and retrieve it 
       /** @var $cacheManager Zend_Cache_Manager */ 
       $cacheManager = $this->getBootstrap() 
        ->bootstrap('cachemanager') 
        ->getResource('cachemanager'); 
       // check for the given key 
       if (!$cacheManager->hasCache($this->getCacheKey())) { 
        throw new Zend_Application_Resource_Exception(
         "You must configure the cachemanager with " 
         . "the key {$this->getCacheKey()}" 
        ); 
       } 
       // set cache for translator 
       Zend_Translate_Adapter::setCache(
        $cacheManager->getCache($this->getCacheKey()) 
       ); 
      } 
      // fetch translate object into local variable 
      $this->_translate = parent::getTranslate(); 
     } 
     return $this->_translate; 
    } 
} 

我創建這個目錄:

/data/cache 
/data/locales 
/data/locales/it 
/data/locales/en 
/data/locales/logs 

/data/locales/en/Foo.php

/** 
* Return Array Key => Translate EN 
* 
*/ 
return array(
    'SEND' => 'Send', 
    'SAVE' => 'Save', 
    'EDIT' => 'Edit', 
); 

/data/locales/it/Foo.php

/** 
* Return Array Key => Translate IT 
* 
*/ 
return array(
    'SEND' => 'Invia', 
    'SAVE' => 'Salva', 
    'EDIT' => 'Modifica', 
); 

libray /我的/View/Helper/T.php

class Zle_View_Helper_T extends Zend_View_Helper_Translate 
{ 
    /** 
    * Shortcut helper to Zend_View_Helper_Translate 
    * You can give multiple params or an array of params. 
    * If you want to output another locale just set it as last single parameter 
    * Example 1: translate('%1\$s + %2\$s', $value1, $value2, $locale); 
    * Example 2: translate('%1\$s + %2\$s', array($value1, $value2), $locale); 
    * 
    * @param string $messageid Id of the message to be translated 
    * 
    * @return string|Zend_View_Helper_Translate Translated message 
    */ 
    public function t($messageid = null) 
    { 
     // TODO replace with php 5.3 
     $arguments = func_get_args(); 
     return call_user_func_array(array($this, 'translate'), $arguments); 
    } 
} 

and fina LLY使用翻譯這樣:

鑑於

<span><?=$this->t('SEND')?>:</span> 
形式

$this->addElement('submit', 'submit', array('label' => 'SAVE')); 

可能有更好的方法,我描述了我! 我希望看看是非常有益的!

+0

你好,謝謝你的快速回復。這當然是一個好方法,但我沒有測試過。我發現另一個解決方案來解決我的問題。無論如何感謝 – cwhisperer

+0

你的解決方案是什麼? – JellyBelly

+0

我在下面發佈了我的解決方案;) – cwhisperer

1

我解決了以下解決方案:

在應用程序中。INI我加

在同一文件夾我創建了一個文件夾郎與我的csv文件,en.csv,fr.csv和de.csv。

在自舉我初始化譯者

protected function _initTranslate() { 
    // Get current registry 
    $registry = Zend_Registry::getInstance(); 
    /** 
    * Set application wide source Locale 
    * This is usually your source string language; 
    * i.e. $this->translate('Hi I am an English String'); 
    */ 
    $locale = new Zend_Locale('en_US'); 

    /** 
    * Set up and load the translations (all of them!) 
    * resources.translate.options.disableNotices = true 
    * resources.translate.options.logUntranslated = true 
    */ 
    $translate = new Zend_Translate('csv', 
        APPLICATION_PATH . '/configs/lang', 'auto', 
        array(
         'disableNotices' => true, // This is a very good idea! 
         'logUntranslated' => false, // Change this if you debug 
         'scan' => Zend_Translate::LOCALE_FILENAME 
        ) 
    ); 

    /** 
    * Both of these registry keys are magical and makes 
    * ZF 1.7+ do automagical things. 
    */ 
    $registry->set('Zend_Locale', $locale); 
    $registry->set('Zend_Translate', $translate); 
    return $registry; 
} 

插件

class SC_Controller_Plugin_LangSelector extends Zend_Controller_Plugin_Abstract { 

public function preDispatch(Zend_Controller_Request_Abstract $request) { 
    $registry = Zend_Registry::getInstance(); 

    // Get our translate object from registry. 
    $translate = $registry->get('Zend_Translate'); 
    $currLocale = $translate->getLocale(); 

    // Create Session block and save the locale 
    $session = new Zend_Session_Namespace('sessionSC'); 

    $lang = $request->getParam('lang', ''); 
    // Register all your "approved" locales below. 
    switch ($lang) { 
     case "de": 
      $langLocale = 'de_DE'; 
      break; 
     case "fr": 
      $langLocale = 'fr_FR'; 
      break; 
     case "en": 
      $langLocale = 'en_US'; 
      break; 
     default: 
      /** 
      * Get a previously set locale from session or set 
      * the current application wide locale (set in 
      * Bootstrap)if not. 
      */ 
      $langLocale = isset($session->lang) ? $session->lang : $currLocale; 
    } 

    $newLocale = new Zend_Locale(); 
    $newLocale->setLocale($langLocale); 
    $registry->set('Zend_Locale', $newLocale); 

    $translate->setLocale($langLocale); 
    $session->lang = $langLocale; 

    // Save the modified translate back to registry 
    $registry->set('Zend_Translate', $translate); 
} 

} 

希望這是一個很好的解決方案,任何評論,歡迎 安德烈

+0

簡單而有效!由於任何翻譯缺少日誌和緩存數組翻譯,所以我的翻譯更復雜一點! ;) – JellyBelly