php - ¡Problema de combinación Zend_Translate-Zend_Navigation y Routing!
zend-framework zend-navigation (2)
Esto no responde directamente a tu pregunta. Pero Zend_View_Helper_Navigation, view helper for navigation, tiene un método setTranslator () que proporcionará una traducción implícita de las ''páginas'' de navegación que ha agregado al contenedor 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);
//...
}
Esto le ahorra tener que llamar manualmente para traducir cada elemento
$navigation->addPages(array(
new Zend_Navigation_Page_Mvc(array(
''label'' => $translate->_(''Wiki''), //<-- This can be eliminated
''action'' => ''index'',
''controller'' => ''article'',
''module'' => ''wiki'',
''pages'' => //...
como se hará automáticamente porque se hizo setTranslator ().
Tengo algunas dificultades con la combinación de Zend_Navigation, Zend_Translate y el enrutamiento necesario.
La navegación de mi sitio se realiza a través de Zend_Navigation en base a un archivo XML. Ahora agregué la traducción al sitio basado en Zend_Translate y lo agregué al siguiente cambio de enrutamiento al programa de arranque:
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);
Luego creé View_Helper con un método 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);
Ahora cuando voy a: "site / en / module / controller / action" funciona bien.
Cuando voy a: "site / da / module / controller / action", la traducción funciona bien, pero mis enlaces de Zend_Navigation apuntan al enlace de idioma ''en'' por defecto "site / en / module2 / controller2 /"
No puedo entender que tu at / da / language. Cualquier ayuda será apreciada.
Saludos cordiales,
Morten
Debido a que Zend_Navigation_Page_Mvc solo busca Módulo, Controlador y Acción, parece que nunca irá a un elemento de enrutamiento adicional.
Una solución podría ser usar una nueva clase como: Zend_Navigation_Page_Mvcl que manejará el lenguaje.
Pero parece un poco complejo, así que encontré una solución usando una navegación más grande que incluye todas las páginas en todos los idiomas.
Esta es mi configuración xml para la navegación de 2 páginas "inicio", "prueba" en francés e inglés:
<?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>
Como pueden ver, es bastante largo solo para 2 páginas. En realidad, tendrá (páginas + 1) x elementos de idiomas en la navegación
Utilicé un ''truco'': la página de inicio está presente dos veces.
- una vez como elemento del menú principal
- una vez como primer elemento del submenú
La idea es definir qué submenú mostrar en función del idioma seleccionado y esto se hace automáticamente a través del enrutador, por lo que todo lo que tienes que hacer es decirle a tu aplicación que dibuje el submenú en lugar del menú. Así que aquí está la línea que uso para eso en mi archivo de diseño :
<?php
echo $this->navigation()->menu()->renderSubMenu()
?>
No vi cómo agregaste Zend_Navigation así que aquí está el mío de 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);
}
?>
Por cierto, en el mismo Bootstrap.php puedo mantener el idioma predeterminado en ''en'', aquí está mi _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 );
}
?>
Y para la traducción, se hace automáticamente si registró su Zend_Translate. En mi ejemplo: menu.home dará:
- Hogar en inglés
- Accueil en francés
Espero que esto ayude.
Preferiría otra solución más sutil pero no la encontré todavía.