In Kohana 3.2 I'm using the default route for a simple controller/action/id setup:
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'home',
'action' => 'index',
'id' => '0',
));
Per the documentation it's pretty easy to wire up controllers and actions to a simple route like this, but route parameters (in this case id) are never accessible in the controllers.
So for example I have a route:
/user/info/123
And the controller handling that route gets called successfully:
public function action_info()
{
$id = $this->request->param('id');
echo "id=" . $id; //nothing
echo "is_null=" . is_null($this->request->param('id')); //1
}
But $this->request->param('id') is always set to null.
This seems like about the simplest example I can come up with, what could I be doing wrong here?
Turns out the company I'm working with extended Kohana with a request->param() function to do something without realizing that was already a function in Kohana, and this broke the built in functionality. Using the built in Kohana request function fixes this problem.
So this turns out to be a non-question as this is the correct way to get request parameters after all. :)
Have you tried this?
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'home',
'action' => 'index',
'id' => '\d+',
));
Related
I've looked at so many Stackoverflow questions regarding this and none of them seem to solve my problem. I just want to have a admin folder and controllers within those. Here is what my route looks so far
/*
* Set the routes. Each route must have a minimum of a name, a URI and a set of
* defaults for the URI.
*/
Route::set( 'default', '(<controller>(/<action>(/<id>)))' )
->defaults( array(
'controller' => 'dashboard',
'action' => 'index',
) );
Route::set('admin','admin(/<controller>(/<action>(/<id>)))')
->defaults(array(
'directory' => 'admin',
'controller' => 'dashboard',
'action' => 'index',
));
As Kingkero said in his comment, move the route above the default one and it will work. if you read the docs on routing properly (I know it takes a while and a few reads for it all to sink in if you're new to it all, I've been there myself) it should be clear that the default route is a catch-all, and that any specific routes you need should come first, and any catch-all type routes after, as they are tried in sequence and when a match is found no more routes are tried.
I have set up two routes, one is the default and the other is one to enable the admin section which has controllers in a sub-directory of the controller directory. These are how they look like:
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'Home',
'action' => 'index',
));
// Admin routes
Route::set('admin', 'admin(/<controller>(/<action>(/<id>)))')
->defaults(array(
'directory' => 'Admin',
'controller' => 'Main',
'action' => 'index',
));
When I navigate to /admin/ or /admin/main I get a 404 error and I can't get it to work. I've also named the classes in the admin sub-directory as Controller_Admin_Main so that should work, right?
Please provide examples to how this should be done correctly. Thank you very much! :)
The problem got fixed by switching the position of the admin route to above the default route in the code. I guess kohana matched the first expression and tried to show a view according to the default route.
I tried this:
Route::set('default_controllers', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'welcome',
'action' => 'index',
));
Route::set('default', '<uri>')
->defaults(array(
'controller' => 'cms',
'directory' => 'cms',
'action' => 'render',
));
But actually I want the 'default' (with the render action) to come first than the default_controllers.
I want it to first check any controllers, and if there is nothing then it should run the second default, render. Render checks the uri in the database and returns the page if exists or else it throws a error.
If i switch on the two's route position, so the 'default' route come before 'default_controllers' then it works fine with the cms pages, but not with the controllers (since it does not look for further routes, after the render function has thrown an error that the page does not exists.)
What do i do here? How can i make them both work?
You basically have two catchall routes here. You should remove one of them, and make your routes more specific. The (<controller>(/<action>(/<id>))) route is actually very bad, and is only provided as an example.
To get this to work, you have to specifically tell the route which controllers to load.
Route::set('default_controllers', '(<controller>(/<action>(/<id>)))', array(
'controller' => 'controller|anotherController|etcController'
))
->defaults(array(
'controller' => 'welcome',
'action' => 'index',
));
If you wanted to, you could write a class to go look for the controllers and cache the result as to not increase load times. You'd then pass this value into the value for the controller key in the array.
Your other route can remain how you had it:
Route::set('default', '<uri>')
->defaults(array(
'controller' => 'cms',
'directory' => 'cms',
'action' => 'render',
));
I have a rule defined in Kohana 3 routing but the ID parameter is not being passed to the method.
I have this in the bootstrap.php file:
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'home',
'action' => 'index',
));
and controller
public function action_home($id=NULL)
{
echo $id;
}
But in the following link example, the ID is usually NULL:
http://example.com/index/123
The ID should be 123 but it isn't. I don't know why.
Yeah the Ko3 routes are ridiculous.
Try removing that $id=null since K03 will assign the vars as parameters:
public function action_home()
{
echo $this->request->param('id');
}
See if that helps.
They were removed from Kohana, please see: http://dev.kohanaframework.org/issues/4357
As zombor stated:
They just don't fit into how Kohana is designed. They should not have been included in 3.0 in the first place.
Also it isn't supposed to handle all routes with the default one. You should define as many as you need.
I'm trying to make a route rule to make my request to the main page in kohana. It's sth of this kind: http://my_site/
And got into trouble here. In docs they write i can make this or that, lots of variants, but no example for mine. Simply saying if i try to do this way
Route::set('main/index', '')
->defaults(array(
'controller' => 'main',
'action' => 'index',
));
then if i write Route::get('main/index')->uri() on page http://my_site/hi i get a link to the same page. If i do it this way
Route::set('main/index', null)
->defaults(array(
'controller' => 'main',
'action' => 'index',
));
No result again, uri callback should have a valid value.
In official manual they suggest this variant
Route::set('default', '(<controller>(/<action>(/<id>)))')
->defaults(array(
'controller' => 'welcome',
'action' => 'index',
));
But i need a rule with a strict match i.e. just http://my_site/, not http://my_site/(<controller>(/<action>(/<id>)))
Is there a way to help me out from this without rewriting Route class?
Thanks in advance
Route::set('main/index', '')
->defaults(array(
'controller' => 'main',
'action' => 'index',
));
Works just for for me if I make sure that route is set before any other route that may match an empty uri. Routes are checked for a match in the order they are added.
If you want to know what if your route was matched (on a development server) you can set the default controller to a non-existing one like 'bogus'. Then Kohana wil throw a Http_Exception_404 and the exception handler will serve you an error page. (Turn on kohana errors if it does not.) On that page click on the 'arguments' link of the first trace of the stack trace. You should then see something like the following:
object Request(18) {
...snip...
protected _route => object Route(5) {
protected _callback => NULL
protected _uri => string(0) ""
protected _regex => array(0)
protected _defaults => array(1) (
"controller" => string(5) "bogus" // the non-existing bogus controller default
)
protected _route_regex => string(6) "#^$#uD"
}
...snip...
}
I got the above by placing the following route before I add any other route (which could match that uri too):
Route::set('main/index', '')
->defaults(array(
'controller' => 'bogus',
));
Also make sure no other route uses the 'main/index' name as it will overwrite the older one. Actually, I just took a look at the code of Route::uri() and guess what. Static routes (routes that have no '<' or '(' in them) should return the current url. Since an empty string is a static route the result Route::uri of that route would always be only the host. Which suggests me you are overriding the 'main/index' route assuming the uri was set to an empty string.
Also when using a NULL as the uri for a route it is assumed it came from the cache and you end up whith an empty route when it did not came from the cache.
Your Route::get('main/index')->uri() returns a relative uri, which in this case would be an empty string. What you want to do is use the url method of the Route class: Route::url('main/index'). This will give you an url that has gone through Url::site as well.