In my project I have some pages defined in my index controller, like ie. the About us page. In order for me not to have to type domain.com/index/about but domain.com/about I have this route:
$route = new Zend_Controller_Router_Route_Static ( 'about', array (
'controller' => 'Index',
'action' => 'about'
) );
$router->addRoute ( 'about', $route );
It does the job. The problem is that sometimes I have 6 or 7 pages and I have to repeat this route 6 or 7 times. Is there a way for me to do a route that would always remove "index" from the url? I would never need a url that has index in it. Thanks!
You can write dynamic routes by avoiding the static route type:
$route = new Zend_Controller_Router_Route(
'/:action',
array (
'controller' => 'index',
'action' => 'index',
)
);
$router->addRoute('pages', $route);
This will add a route called 'pages' that will match any single action in the index controller. The action and controller defined in this route are merely the defaults and as you are not passing the controller as a variable it will always route to the IndexController. The action will default to indexAction but can be overridden by the route, ie:
/about -> IndexController / aboutAction
/contact -> IndexController / contactAction
etc ...
Bear in mind this will override any other routes so you need to structure your routing heirachy properly. Routes defined later in the process will override routes already defined.
For more information check the docs: Zend Framework Standard Router
Related
I need to Add the route to Zend Framwork Application.
I want to display All the Posts from the database where catagory = the controller name
domain.com/action
domian.com/drama
domain.com/thriller
How can i do this ? I gone through the ZF Routes Documentation. But found No Solution.
To be able to do this, you will have to put something like this in your application.ini
resources.router.routes.category.type = "Zend_Controller_Router_Route"
resources.router.routes.category.route = ":category"
resources.router.routes.category.defaults.module = "default"
resources.router.routes.category.defaults.controller = "index"
resources.router.routes.category.defaults.action = "index"
This way, everything that didn't match as a valid controller will be directed as category parameter in index controller index action. Keep in mind to handle invalid category names and trigger 404.
Also, here's a good article about tricks and tips in application.ini
This can be done using addRoute() method in the bootstrap.php file
// Retrieve the front controller from the bootstrap registry
$FrontController = $this->getResource('FrontController');
$router = $FrontController->getRouter();
$router->addRoute('genre',
new Zend_Controller_Router_Route(
':genre',array( 'controller' => 'index' , 'action' => 'index' )) );
To get the Genre in the Controller
echo $this->getRequest()->getParam('genre')
I have a module based Zend application.
One of my modules, called portfolio has only one controller, called index. For this single module, I'd like my route to look like this:
$route = new Zend_Controller_Router_Route('portfolio/:action',
array(
'module' => 'portfolio',
'controller' => 'index',
'action' => 'index'
)
);
This works but messes up all links generated through Zend_Navigation.
Can this routing behavior be achieved, without messing up Zend_Navigation? (i.e. only inbound links are routed through this route. Outbound links are generated with the default route)
I can't use mod_rewrite.
If I defined 2 controllers, A.php and B.php, and in each controller I defined an index action,
how should I define Route::set in the bootstrap.php file?
The default route should do just fine:
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'welcome',
'action' => 'index',
));
Please read the documentation: http://kohanaframework.org/3.2/guide/kohana/routing
That default route will match both controller '/a' and controller '/b', and execute the index action if no other action is specified in the URI.
I have read the documentation and it's not completely clear when and why you would want to create a Route entry.
Basically, a Route entry is needed if you have a URL that does not conform to the normal /controller/action structure. If you have created controller A and controller B both with index actions, you don't need to add routes to bootstrap.php if you are always going to access those actions using the standard URL syntax:
http://www.example.com/A/index
http://www.example.com/B/index
You could leave off "index" since it is the default action if none is specified.
Let's say you want controller A to be the default site controller, meaning that you don't want to have to use A in the URL, you want to use the action right after the domain:
http://www.example.com/index
Then you do need a route to tell Kohana that any URL that is not matched by any routes you have created (or if you have none) should be handled by your default route. You would create this route in bootstrap.php:
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'A',
'action' => 'index'
));
This says that if a user goes to http://www.example.com, Kohana will use the index action of controller A. If the user goes to http://www.example.com/foo, then Kohana will use the foo action of controller A. Any URL that does not match any other controller will go to the A controller. If a user requests an action that A does not handle, he'll get a 404 exception.
You still have the B controller, so that will work fine without any route. If the user goes to http://www.example.com/B/index, Kohana knows about the B controller in the app so it will go to the index action there.
Your problem may be in .htaccess file in kohana folder.
I needed to change the "RewriteBase" to the Kohana folder ('base_url' from Kohana::init in bootstrap.php file), otherwise I landed in '404 - no object found'.
Then the default route should do just fine.
I have the following code in my PortfolioController:
function index()
{
$this->set('posts', $this->Portfolio->find('all'));
}
function view ( $id, $slug )
{
$post = $this->Portfolio->read(null, Tiny::reverseTiny($id));
$this->set(compact('post'));
}
However in order to get the view to remove /view/ from the URL, I have added the following to my routes: Router::connect('/portfolio/*', array('controller' => 'portfolio', 'action' => 'view'));
This breaks the index method as it overrides it by calling the view method instead and shows a blank view
How do I fix this?
What are you trying to do exactly? (And what's with $slug?)
It sounds like what you want to do is remove the action (or at least the view() action?) from displaying in the URL, amirite? Kind of like the default pages_controller display() method - catch-all action for static pages?
How do I fix this?
Well, I'd suggest starting with un-breaking that route, because otherwise it's doing exactly what you told it to:
Router::connect('/portfolio/*',
// * is a wildcard matching anything & everything after /portfolio/
array('controller' => 'portfolio',
// and routing to portfolio's view() action, with or w/o required $args to pass
'action' => 'view'));
so what you see when you call index() is not a blank view, it's a suppressed fatal error, which is what happens when index() reroutes to view() and doesn't have an $id to pass in for the first arg.
Note the ending DS. Route order matters; first rule that catches, wins. The following routes would all map to index by default if the url's action were omitted, but they're not the same.
// Targets inside the controller (its methods)
Router::connect('/portfolio/',
array('controller' => 'portfolio', 'action' => 'index'));
is not the same as
// Targets the controller
Router::connect('/portfolio',
// Specifies the default controller action, can be whatever
array('controller' => 'portfolio', 'action' => 'index'));
For what you're trying to do, it should be
// Targets the controller
Router::connect('/portfolio',
// Routes to 'controller default method' which is index() by Cake default
array('controller' => 'portfolio');
This allows Cake to enforce auto default mapping to the controller's index() whenever the action is missing from the URL.
It would still have worked except for the trailing DS and trailing asterisk. The same rule that should catch index() reroutes to view() instead, thanks to the trailing asterisk targeting all actions in portfolio.
Hence Foo's suggestion doesn't work -> trailing DS + wildcard:
Router::connect('/portfolio/',
// the trailing DS changes it to target 'inside portfolio' instead of 'portfolio'
array('controller'=>'portfolio', 'action'=>'index'));
// trailing arbitrary wildcard maps any / all actions directly to view() method
Router::connect('/portfolio/*',
array('controller' => 'portfolio', 'action' => 'view'));
Which just ensures ALL actions in portfolio map directly to portfolio view() method (including /portfolio/index action). Do not pass go, etc. Any portfolio action resolves to the wildcard no matter what, aliasing the whole controller to that method. So you could knock the DS off the first route but any url starting with /portfolio that isn't /portfolio would still route to view(). Including the url /portfolio/index.
Try this:
// catches portfolio/index() without index in the url
Router::connect('/portfolio',
array('controller' => 'portfolio'));
// maps to portfolio/view() without view in url, just /portfolio/integer id
Router::connect('/portfolio/:id',
array('action'=>'view', array('id' => '[0-9]+'));
// routes everything else in portfolio as usual
Router::connect('/portfolio/:action/*',
array('controller'=>'portfolio'));
Routes can be tricky. Here are some links; HTH. :)
http://bakery.cakephp.org/articles/Frank/2009/11/02/cakephp-s-routing-explained
http://book.cakephp.org/view/46/Routes-Configuration
I'm new to CakePHP myself, but I believe you can add
Router::connect('/portfolio/', array('controller' => 'portfolio', 'action' => 'index'));
Before the route with the star.
as per my knowledge is concern
you should give like this:
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
I mean you should changes the aliases of the controller name.
Router::connect('/portfolios/*', array('controller' => 'portfolios', 'action' => 'view'));
I'm using Zend FW 1.9.2, want to disable the default routes and supply my own. I really dislike the default /:controller/:action routing.
The idea is to inject routes at init, and when the request cannot be routed to one of the injected routes it should be forwarded to the error controller. (by using the defaultly registere Zend_Controller_Plugin_ErrorHandler)
This all works fine, until I disable the default routes with $router->removeDefaultRoutes();
When I do that, the error controller no longer routes unrouted requests to the error controller. In stead, it routes all unrouted requests to indexAction on the default controller.
Anyone have any idea how to disable the default /:controller/:action routing but KEEP the route error handling?
Basically, this is what I do:
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$router->removeDefaultRoutes(); // <-- when commented, errorhandling works as expected
$route = new Zend_Controller_Router_Route_Static(
'',
array('controller' => 'content', 'action' => 'home')
);
$router->addRoute('home', $route);
The problem when you remove the default routes is that Zend no longer understands the urls /:module/:controller/:action, so whenever a route is sent, it gets routed to the default Module, index Controller, index Action.
The Error plugin works on the postDispath method of the controller dispatch and it works because in the standard router if the controller, or module, or action isn't found it throws a error.
To enable custom routes in this config you must write a new plugin that works on the preDispatch, and check if the route and then redirect to the error plugin in the event it's a invalid URL.
When you remove the default routes, you remove the default route that the error handler plugin utilizes. This means that when it tries to route to
array('module' => 'default, 'controller' => 'error', 'action' => 'index')
none of your routes match this setup. Thus it'll fail. I suppose you could add just this route from the default like so:
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$router->removeDefaultRoutes(); // <-- when commented, errorhandling works as expected
// Re-add the error route
$router->addRoute(
'error',
new Zend_Controller_Router_Route (
'error/:action',
array (
'controller' => 'error',
'action' => 'error'
)
)
);
$route = new Zend_Controller_Router_Route_Static(
'',
array('controller' => 'content', 'action' => 'home')
);
$router->addRoute('home', $route);
I encountered the same issue for an old application, here is what solved my problem:
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();
$router->removeDefaultRoutes();
// forward all routes to the not found error action
$route = new Zend_Controller_Router_Route('*', array('controller'=>'error', 'module'=>'error', 'action'=>'notfound'));
$router->addRoute('default', $route);
// After that add your routes.
$route = new Zend_Controller_Router_Route_Static('', array('controller' => 'content', 'action' => 'home'));
$router->addRoute('home', $route);
You need to add this route first as it needs to be the last processed.
And in ErrorController I defined:
public function notfoundAction()
{
throw new Zend_Controller_Action_Exception('This page does not exist', 404);
}
This way any route that is not matched to our routes will use the default error handler.