Zend_Translate - проблема комбинации Zend_Navigation и Routing - PullRequest
9 голосов
/ 27 февраля 2010

У меня возникли некоторые трудности с сочетанием Zend_Navigation, Zend_Translate и необходимой маршрутизации.

Навигация по моему сайту осуществляется через Zend_Navigation на основе XML-файла. Теперь я добавил перевод на сайт, основанный на Zend_Translate, и добавил следующее изменение маршрутизации к начальной загрузке:

protected function _initRoutes()

    $config = new Zend_Config($this->getOptions());
    $languages = array_keys($config->languages->toArray());
    $zl = new Zend_Locale();
    $lang = in_array($zl->getLanguage(), $languages)
                  ? $zl->getLanguage() : 'en';

    $zfc = Zend_Controller_Front::getInstance();


    // add language to default route
    $route = new Zend_Controller_Router_Route(
            ':lang/:module/:controller/:action/*',
      array('controller'=>'index',
                'action' => 'index',
                'module'=>'default',
                'lang'=>$lang));

    $router = $zfc->getRouter();
    $router->addRoute('default', $route);
    $zfc->setRouter($router);

Затем я создал View_Helper с методом preDispatc:

    $language = $request->getParam('lang','');

 if ($language !== 'en' && $language !== 'da')
     $request->setParam('lang','en');

 $language = $request->getParam('lang');
 if ($language == 'en')
     $locale = 'en_EN';
 else
     $locale = 'da_DK';

 $zl = new Zend_Locale();
 $zl->setLocale($locale);
 Zend_Registry::set('Zend_Locale', $zl);

 $translate = new Zend_Translate('csv', APPLICATION_PATH . '/configs/language/'. $language . '.csv' , $language);
 Zend_Registry::set('Zend_Translate', $translate);

Теперь, когда я захожу на: "site / ru / module / controller / action", он работает нормально.

Когда я захожу на: "site / da / module / controller / action", перевод работает нормально, но мои ссылки из Zend_Navigation указывают на сайт по умолчанию 'en' language link "site / ан / module2 / controller2 / "

Не могу понять, что у тебя на / да / языке. Любая помощь будет оценена.

С уважением,

Morten

Ответы [ 2 ]

1 голос
/ 16 сентября 2011

Поскольку Zend_Navigation_Page_Mvc проверяет только модуль, контроллер и действие, похоже, что он никогда не перейдет к дополнительному элементу маршрутизации.

Одним из решений может быть использование нового класса, такого как: Zend_Navigation_Page_Mvcl, который будет обрабатывать язык.

Но это кажется немного сложным, поэтому я нашел одно решение, используя более крупную навигацию, которая включает все страницы на всех языках.

Это мой xml конфиг для навигации по 2 страницам "home", "test" на французском и английском:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <nav>
        <fr>
            <label>menu.home</label>
            <params>
                <lang>fr</lang>
            </params>
            <action>index</action>
            <controller>homepage</controller>
            <route>langcontrolleraction</route>
            <pages>
                <home>
                    <label>menu.home</label>
                    <params>
                        <lang>fr</lang>
                    </params>
                    <action>index</action>
                    <controller>homepage</controller>
                    <route>langcontrolleraction</route>
                </home>
                <test>
                    <label>menu.wallet</label>
                    <params>
                        <lang>fr</lang>
                    </params>
                    <action>index</action>
                    <controller>wallet</controller>
                    <route>langcontrolleraction</route>
                </test>
            </pages>
        </fr>
        <en>
            <label>menu.home</label>
            <params>
                <lang>en</lang>
            </params>
            <action>index</action>
            <controller>homepage</controller>
            <route>langcontrolleraction</route>
            <pages>
                <home>
                    <label>menu.home</label>
                    <params>
                        <lang>en</lang>
                    </params>
                    <action>index</action>
                    <controller>homepage</controller>
                    <route>langcontrolleraction</route>
                </home>
                <test>
                    <label>menu.wallet</label>
                    <params>
                        <lang>en</lang>
                    </params>
                    <action>index</action>
                    <controller>wallet</controller>
                    <route>langcontrolleraction</route>
                </test>
            </pages>
        </en>
    </nav>
</config>

Как видите, он довольно длинный, всего для 2 страниц. На самом деле у вас будет (страниц + 1) x языков в навигации

Я использовал «трюк»: домашняя страница присутствует дважды.

  • один раз как пункт главного меню
  • один раз как первый пункт подменю

Идея состоит в том, чтобы определить, какое подменю будет отображаться на основе выбранного языка, и это автоматически выполняется через маршрутизатор, поэтому все, что вам нужно сделать, это указать приложению нарисовать подменю вместо меню. Итак, вот строка, которую я использую для этого в моем файле макета :

<?php 
echo $this->navigation()->menu()->renderSubMenu() 
?>

Я не видел, как вы добавили Zend_Navigation , так что вот мой от Bootstrap.php :

<?php
protected function _initNavigation() {
    $config = new Zend_Config_Xml(Zend_Registry::get ( 'config' )
            ->resources->navigation->file, 'nav');
    $navigationContainer = new Zend_Navigation($config);
    // Store the container in the proxy helper:
    $view = $this->getResource ( 'view' );
    $view->getHelper('navigation')->setContainer($navigationContainer);
}
?>

Кстати, в том же Bootstrap.php Я могу оставить язык по умолчанию 'en', вот мой _initRoutes () :

<?php
protected function _initRoutes() {
    $router = Zend_Controller_Front::getInstance ()->getRouter ();
    $router->removeDefaultRoutes ();
    $myRoute = new Zend_Controller_Router_Route (
        ':lang/:controller/:action',
        array (
            'lang' => 'en',
            'controller' => 'index',
            'action' => 'index',
        )
    );
    $router->addRoute ( 'langcontrolleraction', $myRoute );
}
?>

И для перевода это делается автоматически, если вы зарегистрировали свой Zend_Translate. В моем примере: menu.home выдаст:

  • Home на английском
  • Accueil на французском

Надеюсь, это поможет.

Я бы предпочел другое, более тонкое решение, но пока не нашел.

1 голос
/ 20 мая 2011

Это не дает прямого ответа на ваш вопрос. Но Zend_View_Helper_Navigation, помощник вида для навигации, имеет метод setTranslator (), который обеспечивает неявный перевод навигационных «страниц», добавленных вами в контейнер Zend_Navigation.

class MyModule_Bootstrap extends Zend_Application_Module_Bootstrap
{
   protected function _initMyModuleNavigation()
   {
    $langSess = new Zend_Session_Namespace('language');
    $translate = $langSess->translate;

    $this->getApplication()->bootstrap('navigation');

    $view = $this->getApplication()->getResource('view');

    $navigationHelper = $view->getHelper('navigation');

    $navigation = $navigationHelper->getContainer();

    $navigationHelper->setTranslator($translate);

    //...
}

Это избавляет вас от необходимости вручную переводить для каждого элемента

$navigation->addPages(array(
        new Zend_Navigation_Page_Mvc(array(
            'label' => $translate->_('Wiki'), //<-- This can be eliminated
            'action' => 'index',
            'controller' => 'article',
            'module' => 'wiki',
            'pages' => //...

как это будет сделано автоматически, потому что setTranslator () был сделан.

...