ZF语言和翻译

时间:2011-12-02 12:23:54

标签: php zend-framework zend-translate

我需要一个很好的语言工作示例,并在ZF内翻译。

我的需求如下: 如果未选择lang,则'en'应为默认值。 (在页面顶部有一个lang选择器。) 郎应该存储在会话中。 翻译应该通过csv文件完成。 我希望语言中的语言不可见,因此如果可能,我不需要重新配置路由。

我找到了一些教程,但他们并没有真正为我工作......

任何帮助将不胜感激...... 问候 安德烈

2 个答案:

答案 0 :(得分: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']);

    }
}

库/我的/应用/资源/ Translate.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 /我/视图/助手/ 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);
    }
}

最后使用翻译:

在视图中:

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

形式:

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

可能有更好的方法,我已经描述过了! 我希望退房是非常有帮助的!

答案 1 :(得分:1)

我用以下解决方案解决了:

在application.ini中我添加了

resources.frontController.plugins.LangSelector = "SC_Controller_Plugin_LangSelector"

在同一个文件夹中,我创建了一个包含我的csv文件的文件夹,en.csv,fr.csv和de.csv。

在boostrap中,我初始化了翻译器

 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);
}

}

希望这是一个很好的解决方案,欢迎任何评论 安德烈