I'm trying to make a Router that can respond to this structure:
module/controller/action/id and module/controller/action/page
The only difference is is 'id' or 'page'. I'm using this code:
$routeAdmin = new Zend_Controller_Router_Route(
'administrador/:controller/:action/:id/:pg',
array(
'module' => 'administrador',
'controller' => 'index',
'action' => 'index',
'id' => 0,
'pg' => 1
),
array(
'id' => '\d+',
'pg' => '\d+'
)
);
$router->addRoute('administrador', $routeAdmin);
The problem is that in some situations i want:
'http://www.domain.cl/administrador/productos/2' => (module=>administrador, controller=>productos,page=>2) but with the router 'administrador' result in 'http://www.domain.cl/administrador/productos/index/0/2' (module=>administrador, controller=>productos,action=>index,id=>0,page=>2)
I'm very confused about how it works for cases like this. I tried to make two router where the first only have 'id' param and the other 'page' param. And from url helper use it like:
$this->url(array('module' => 'administrador', 'controller' => 'productos', 'action' => 'index', 'id' => 0), 'administradorId');
$this->url(array('module' => 'administrador', 'controller' => 'productos', 'action' => 'index', 'page' => 1), 'administradorPg');
But when I used the routers always select the last one added to the router ($router->addRoute('routerIdentifier', $route);)
Thanks
I have had a similar issue and I got around this by defining just one route like this
$routeAdmin = new Zend_Controller_Router_Route(
'administrador/:controller/:action/:id/:pg',
array(
'module' => 'administrador',
'controller' => 'index',
'action' => 'index',
'id' => 0
),
array(
'id' => '\d+'
)
);
$router->addRoute('administrador', $routeAdmin);
In your actions you'd then need to get the id and check for it somewhere where that id might be, for example if you were in /administrador/events/view/1 then you might look in the events table or if you were in /administrador/pages/view/1 then you would look for a page.
But the problems really start when the id could be either an event or a page in a given controller and action. The only real way around this is explicitly set the type of id your using for example
/administrador/events/view/index/id/1
or
/administrador/pages/view/index/page/1
If you want to remove the index part then set up routes like
$routeAdmin = new Zend_Controller_Router_Route(
// Remove the action from here and explicitly set the controller
'administrador/pages/:pg',
array(
'module' => 'administrador',
'controller' => 'pages',
// Then set the default action here
'action' => 'index',
'pg' => 0
),
array(
'pg' => '\d+'
)
);
$router->addRoute('administradorpages', $routeAdmin);
What your asking for basically results in a lot of guess work and therefore risk of producing unexpected results.
Have a look at dynamic segments in routes. It is not exactly what you want, but it might be helpful in your case.
Related
I'm trying to create a dynamic route in a ZF2 project. It will be something like "domain.com/companyurl/products". The company url is dynamic. I did it:
'company' => array(
'type' => 'Segment',
'options' => array(
'route' => '[/:company]',
'defaults' => array(
'controller' => 'IndexController',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
...
),
),
But I always have to pass the company parameter in a route.
$this->url('company/products', array('company' => 'companyurl'));
Is there some way to specify a base route at the runtime, like a base url, then all route will follow it? Something like this:
$this->url('products');
or
$this->url('company/products');
In the both cases I already specified the base route value.
I hope you understand what I mean. Thanks.
There is a $reuseRouteParams option that you can use in the URL helper:
$this->url($name, $params, $options,$reuseMatchedParameters);
If you set this to true it will reuse the previous route match value of companyUrl.
You can read more on this in the docs here.
For SEO purpose, I have to put all form data into an URL. Here's the routing :
Router::connect('/liste-voitures/:marque/:modele/:categorie/:energie',
array(
'controller' => 'vehicules',
'action' => 'index',
),
array(
'pass' => array(
'marque',
'modele',
'categorie',
'energie'
)
)
);
So in my index action I've built an array with the values and pass it to the redirect function to match with the route :
$urlbuilding = array(
'action' => 'index',
'marque' => 'volvo-3',
'modele' => 'C30-2',
'categorie' => 'citadine',
'energie' => 'diesel'
);
$this->redirect($urlbuilding);
This is working fine as I get to the URL :
/liste-voitures/volvo-3/C30-2/citadine/diesel/
Except for the pagination. The page numbers are pointing to the URL :
/vehicules/index/volvo-3/C30-2/citadine/diesel/page:2/sort:Vehicule.recommande/direction:desc
and it should be
/liste-voitures/volvo-3/C30-2/citadine/diesel/page:2/sort:Vehicule.recommande/direction:desc
I tried to change the url by setting Pagination options :
$this->Paginator->options = array(
'url' => array(
'action' => 'index',
'marque' => $this->request->params['marque'],
'modele' => $this->request->params['modele'],
'categorie' => $this->request->params['categorie'],
'energie' => $this->request->params['energie']
)
);
But it didn't work better.
I then tried to add a route with a wildcard :
Router::connect('/liste-voitures/:marque/:modele/:categorie/:energie/*',
array(
'controller' => 'vehicules',
'action' => 'index',
),
array(
'pass' => array(
'marque',
'modele',
'categorie',
'energie',
'page',
'sort',
'direction'
)
)
);
But It did'nt work. And I'm not yet trying to get the page, sort and direction values prettier as in
/liste-voitures/volvo-3/C30-2/citadine/diesel/2/Vehicule.recommande/desc
... but that would be my next step ;)
Do anyone would mind telling me if I'm doing something wrong ? It's been days since I last had the feeling to move forward with this project. I would be very grateful if someone could drive me on the right way ! :)
SEO urls and Cakephp pagination urls are two different sides of a coin!
For urls use your own logic and pass parameters to pagination settings, in your views you can create seo friendly urls and will be able to use paginator component of cakephp.
Router::connect('/liste-voitures/:marque/:modele/:categorie/:energie/:page/:sort/:direction',
array(
'controller' => 'vehicules',
'action' => 'index',
),
array(
'pass' => array(
'marque',
'modele',
'categorie',
'energie',
'page',
'sort',
'direction'
)
)
);
This should be your routing and use your own logic too create pagination urls, do not use paginate helper.
i need to route urls like in zf1.
in particular i need that these urls will be automatically redirect to appropriate actions without specify a new route every time.
/site/getData
/site/getData?param=5&par2=test
/site/getOther
...
So a segment route doesn't work, i've tried a Literal route but i can't reach a working solutions.
Anyone can help me?
Thanks a lot
This should be solved by a pretty default segment route like the one provided in the documentation.
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/:controller[/:action]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]+',
'action' => '[a-zA-Z][a-zA-Z0-9_-]+',
),
'defaults' => array(
'controller' => 'default-controller-alias',
'action' => 'index',
),
)
Now if you set up your controller names like the following:
'controllers' => array(
'invokables' => array(
'sites' => 'Namespace\Controller\SitesController',
'other' => 'Namespace\Controller\OtherController'
Then you should be able to achieve exactly what you want. And to create params to your route, you simply use the ViewHelper correctly ;)
$this->url('routename',
array(
'controller' => 'site',
'action' => 'getData'
),
array (
'query' => array(
'param1' => 'foo',
'param2' => 'bar',
'paramN' => 'baz',
)
)
)
My Zend Framework 2 application has a route definition that's trying to mimic the default Zend Framework 1 route. It looks like:
'router' => array(
'routes' => array(
'default' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'defaults' => array(
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'wildcard' => array(
'type' => 'wildcard',
),
),
),
),
),
It matches routes just fine, but I can't assemble routes with arbitrary parameters using the Url view helper.
For example,
$this->url('default', array('controller' => 'test', 'action' => 'test', 'id' => 5));
results in /test/test instead of /test/test/id/5.
Does anyone know how to assemble partial routes like this? Or is there a better way of getting ZF1-style routes?
It turns out that you need to specify the entire route name (including child routes) in the Url view helper.
Using the router defined in my question, the proper view helper call would look like:
$this->url('default/wildcard', array('controller' => 'test', 'action' => 'test', 'id' => 5));
which would result in a url of /test/test/id/5.
I need a Zend_Controller_Route_Route with controller => 'downloads', action => 'index' and a parameter variable which is infinite.
www.domain.com/downloads/this/is/the/path/to/the/folder
should redirect to
DownloadsController > indexAction
I was thinking about something like the following:
'downloads' => array(
'route' => 'downloads/*',
'defaults' => array('controller' => 'downloads', 'action' => 'index')
But how do I request the * as a parameter?
You can use a RegEx Route http://framework.zend.com/manual/de/zend.controller.router.html#zend.controller.router.routes.regex
$router = Zend_Controller_Front::getInstance()->getRouter(); // returns a rewrite router by default
$route['default'] = new Zend_Controller_Router_Route_Regex(
'/downloads/(.*)',
array(
'controller'=> 'Downloads',
'action' => 'index',
),
array(
1 => 'downloadpath',
)
);
$router->addRoute('default', $route['default']);
I havent tested it but something like that shoudl work