2012-02-24 13 views
5

He leído todas las publicaciones sobre enrutamiento y documentación de Zend, pero todavía no puedo resolver este problema.Zend Problemas de enrutamiento

Tengo una aplicación de varios idiomas con dos módulos: por defecto y admin. La selección de idioma está funcionando bien (en un controlador routeShutdown Plugin), pero tiene algunos problemas para configurar el router:

Quiero tener éstos de trabajo URL:

/ 
/controller 
/controller/action 
/action     (default controller) 
/controller/param  (default action) 
/admin 
/admin/admin-controller 
/admin/admin-controller/action 

y utilizando el selector de idioma sería :

/en 
/en/controller 
/en/controller/action 
/en/action     (default controller) 
/en/controller/param  (default action) 
/en/admin/admin-controller 
/en/admin/admin-controller/action 

he añadido esto a mi archivo bootstap (index.php):

$frontController = Zend_Controller_Front::getInstance(); 
$router = $frontController->getRouter(); 
$router->removeDefaultRoutes(); 
$router->addRoute('langmodcontrolleraction', 

new Zend_Controller_Router_Route('/:lang/:module/:controller/:action', 
    array('lang' => ':lang')) 
); 

$router->addRoute('langmodcontroller', 
new Zend_Controller_Router_Route('/:lang/:module/:controller', 
    array('lang' => ':lang', 
     'action' => 'index')) 
); 

$router->addRoute('langmod', 
new Zend_Controller_Router_Route('/:lang/:module', 
    array('lang' => ':lang', 
     'action' => 'index', 
     'controller' => 'index')) 
); 

$router->addRoute('lang', 
new Zend_Controller_Router_Route('/:lang', 
    array('lang' => ':lang', 
     'action' => 'index', 
     'controller' => 'index', 
     'module' => 'default')) 
); 

$frontController->setControllerDirectory(array(
'default'=>BASE_PATH.'app/modules/default/controllers', 
'admin'=>BASE_PATH.'app/modules/admin/controllers'));  

Con el fin de comprobar cómo el router es analizar la URL, he añadido un var_dump al plugin routeShutdown:

Introducción a /es, me sale:

array 
'lang' => string 'en' (length=2) 
'action' => string 'index' (length=5) 
'controller' => string 'index' (length=5) 
'module' => string 'default' (length=7) 

lo cual está bien. Pero cuando entro a /es/Controller1 me sale:

array 
'lang' => string 'en' (length=2) 
'module' => string 'controller1' (length=8) 
'action' => string 'index' (length=5) 
'controller' => string 'index' (length=5) 

Se ajuste del módulo de "Controller1". ¿Cómo puedo decirle al enrutador que configure el valor predeterminado para el módulo? Y para una URL como/en/controller/param? (configuración de módulo y acción por defecto)

Respuesta

6

Me temo que tendrá que replantearse un poco su esquema de URL, o cambiar la forma en que se configuran sus rutas, ya que ha topado con dos limitaciones de la forma en que ZF el enrutamiento funciona

La primera es que el enrutador no tiene conocimiento de lo que es o no es un módulo, controlador o acción válido; todo lo que hace es hacer coincidir las cadenas en la URL con las variables de la ruta. Lo hace comprobando cada ruta en sucesión, en orden inverso, hasta que encuentra una coincidencia. Cuando marque /en/controller, primero verifica su ruta /:lang, que no coincidirá. A continuación, comprueba /:lang/:module, que coincidirá, porque /:lang/:module coincidirá/cualquier cosa/cualquier cosa a menos que indique lo contrario.

Con esto en mente, usted no será capaz de tener:

/en/controller 
/en/action 

a menos que establezca algunas restricciones, como una URL como /en/foo siempre se corresponde con cualquiera de los dos se define pasado.

Si usted tiene un número bastante reducido de acciones/controladores que no cambian a menudo, la forma más sencilla en torno a esto es codificar en algunos valores posibles para la segunda de las dos rutas, por ejemplo:

$router->addRoute('langmod', new Zend_Controller_Router_Route(
    '/:lang/:module', 
    array(
     'lang' => ':lang', 
     'action' => 'index', 
     'controller' => 'index' 
    ), 
    array(
     'module' => '(foo|bar|something)' 
    ) 
)); 

reemplazar foo, bar etc. con nombres de módulo válidos. Ahora, cuando pulses /en/controller1, no coincidirá con esta ruta porque el controlador1 no coincide con el patrón de expresiones regulares definido para la variable del módulo: Necesitaría una ruta de /:lang/:controller (o posiblemente /:lang/:controller/:action) para que coincida.

Ha preguntado cómo establece un valor predeterminado para algunas de las variables.En realidad, ya estás haciendo esto con la acción en algunas de tus rutas, pero para el controlador/módulo no funcionará del modo que esperas. Si tomamos la ruta langmodcontroller y el cambio a esto:

$router->addRoute('langmodcontroller',new Zend_Controller_Router_Route(
    '/:lang/:module/:controller', 
    array(
     'lang' => ':lang', 
     'controller' => 'index' 
     'action' => 'index' 
    ) 
)); 

ahora hay un valor predeterminado para la variable de control. Si simulamos por un segundo que esta era la única ruta, una solicitud para /en/blog ahora coincidiría con esto y establecería los parámetros de solicitud en lang = en, módulo = blog, controlador = índice, acción = índice. /en/blog/index/foo también coincidiría con esta ruta, y le daría module = blog, controller = index, action = foo. Pero tenga en cuenta que aunque el controlador = indexe aún necesita eso en la URL. Entonces, la limitación número dos es que siempre necesita la variable en la URL (incluso si está configurada en su valor predeterminado) siempre y cuando tenga algo que no sea el predeterminado.

Con estas limitaciones en mente me gustaría sugerir que vaya con algo como esto (que se define en este orden):

/:lang/:controller/:action/ (with 'index' defaults for controller and action) 
/:lang/:action (with 'action' restricted to some predefined values) 
/:lang/admin/:controller/:action (with 'admin' as a string in the URL, and :module set to 'admin' as the default) 

Esto le daría URL así:

/en 
/en/controller 
/en/controller/action 
/en/action 
/en/controller/param 
/en/admin/controller 
/en/admin/controller/action 

que es más o menos lo que buscas

El enrutamiento en ZF es muy potente, solo necesita conocer sus peculiaridades.

+0

esta es una respuesta muy útil, su explicación es perfecta, ahora entiendo cómo funciona el enrutamiento :) ¡gracias! Cuando llego a 15 rep. Voy a votar tu respuesta. Aquí está mi sitio web, donde implementaré esto: [tryandsay.com] (http://www.tryandsay.com) – Gustavo