In Kohana 2, a controller function could have arguments in it without needing to write a route for it.
url: /some/arg/is/here
and in the controller, i could simply have four args, of any name, and they'd be automatically accessible from within the function.
public function myFunc($a, $b, $c, $d) {}
but in Kohana 3, I have to go write a route for type of route I want to have. Is there a route I can use that will make my url and args play nice with each other without me having to do extra work each time i write a new function?
All args must be specified in the route, but can be made optional. In this instance you may want to change the default route to something like...
Route::set('default', '(<controller>(/<action>(/<arg1>(/<arg2>(/<arg3>(/<arg4>))))))');
You can then reference the args by using "request"...
$this->request->param('arg1');
$this->request->param('arg2');
$this->request->param('arg3');
$this->request->param('arg4');
You could obviously have more than 4 if you needed them.
FYI Kohana 3 is a complete rewrite from scratch. Kohana 2 and 3 could be considered two separate frameworks.
As for the route, you maybe want to use a catch-all route. Check it out here Kohana 3.3 catch-all route
I would advise against using it, because it looses the whole purpose of KO3 routing flexibility.
Also, you can't access parameters as method arguments anymore since KO 3.1 (I think). Instead use the Request class to retrieve the parameters like so: $this->request->param('abc'); or instantiate the Request class if you're using it outside the controller like so Request::current()->param('abc');
Related
I'm trying to set up a routing prefix in cakephp 3 so any URLs starting with /json/ get the prefix key set and I can change the layout accordingly in the app controller. Other than that, they should use the usual controller and action. I have added the following to routes.php
$routes->prefix('json', function($routes) {
$routes->connect(
'/:controller/:action/*',
[],
['routeClass' => 'InflectedRoute']
);
});
I want to direct all requests with json as first url segment to controller specified in second url segment. e.g. /json/users/add_account_type/ goes to users controller. However when accessing this URL I get the message:
Error: Create the class UsersController below in file:
src/Controller/Json/UsersController.php
whereas I want it to be using
src/Controller/UsersController.php
I think this should be possible but I can't quite see what I'm doing wrong when consulting the book. Have partly based my code on: CakePHP3.x controller name in url when using prefix routing
Thanks a lot in advance
That's simply how prefix routing now works in 3.x, as explained in the docs, prefixes are being mapped to subnamespaces, and thus to separate controllers in subfolders.
http://book.cakephp.org/3.0/en/development/routing.html#prefix-routing
If you'd wanted to change that behavior (I don't really see why), one way would be to implement a custom ControllerFactory dispatcher filter.
http://book.cakephp.org/3.0/en/development/dispatch-filters.html
On a side note, the RequestHandler component supports layout/template switching out of the box, so maybe you should give that a try.
http://book.cakephp.org/3.0/en/controllers/components/request-handling.html
http://book.cakephp.org/3.0/en/views/json-and-xml-views.html
Prefix routing is a way of namespacing parts of your routes to a dedicated controller. It seem that what you want is a scope and not a prefix, for what you describe:
Router::scope('/json', function($routes) {
$routes->fallbacks('InfledtedRoute')
});
I'm just new to Laravel but I immediately fell in love with it. As a not so super experienced php developer I do find the official documentation, although very expansive, somewhat complicated to use and find everything I need.
My question is about the Routing component. As the documentation states you can assign a route to a controller with the Route::controller method. So if I want a Blog controller for all /blog/ routes I assign it like this:
Route::controller('blog', 'BlogController');
So then if I'd like to acces all my blog posts I acces the the getIndex method by www.foo.com/blog or www.foo.com/blog/index
But let's say I'd like to be able to display categories via a getCategory method. My url would look like www.foo.com/blog/category and if, for example, I want to get the news category from the DB by slug, I'd like to use: www.foo.com/blog/category/news as the URI.
My question now is, how do I pass the slug to the url and access it in the getCategory method? Do I need specify it via Route::get('blog/category/{slug}', 'BlogController#getCategory') or is there a way to use Route::controller('blog', 'BlogController') and to send and acces parameters from the URL in the getCategory method?
I already tried to find it via google and in the official documentation, but I couldn't find a crystal clear answer to this problem...
You can simply add parameters to your getCategory method:
public function getCategory($category) {
die($category);
}
If you initialize it to null in the parameter list, it becomes optional. Alternatively, you can always pull parameters from the Input object but they would need to be passed in querystring format:
$category = Input::get('category');
With that said, I'd caution against using the Controller route. It's handy and mimics traditional MVC frameworks, but I believe it's planned to be deprecated -- and honestly, you miss out on some pretty flexible features.
using Route::controller('blog', 'BlogController'); allows you to define a single route to handle every action in a controller using REST naming conventions.then you have to add methods to your controller, prefixed with the HTTP verb they respond to. That means if you have a method called getIndex() it will be executed when there is a GET request to the url "yoursite.com/blog".
To handle POST requests to the same url add a method prefixed with post(ex: postComment()) and so on for other http verbs PUT, PATCH and DELETE.
I think you want something more customized, so you can use a resource controller:
Route::resource('blog', 'BlogController');
This will generate some RESTful routes around the blog resource, run php artisan routes in your project folder to see the generated routes, it should be something like this:
Verb Path Action Route Name
GET /blog index blog.index
GET /blog/create create blog.create
POST /blog store blog.store
GET /blog/{blog} show blog.show
GET /blog/{blog}/edit edit blog.edit
PUT/PATCH /blog/{blog} update blog.update
DELETE /blog/{blog} destroy blog.destroy
in the action column are the functions that you should have in the controller.
If you want to define more routes you can simply do it with Route::get or Route::post in the routes.php file
I hope this will make it more clear for you, enjoy routing with Laravel!!!
Let say I have my user controller and there are action_index(), action_login(), action_logout() action_profile($userid) methods in it. I want to make a routing that
www.mysite.com/user/xxxx
checks the xxxx part of the url and if it is not one of (login,logout,index) it calls action_profile(xxxx) method.
Now I am doing it like this:
my routing routs all www.mysite.com/user/xxxx type of requests to action_index and it checks whether xxxx is a method name or not. If it is not a method name it calls action_profile(xxxx)
However, I think it is possible in a better way. How can I do it better?
Hmm I'm not sure if I understand what you're asking. Routes in laravel are on a first match basis.
So you could just add the following to your routes.php:
Route::get('user/(:num)', 'user#profile');
Route::controller('user');
The first line is for routing user/xxx to action_profile() in user controller where xxx is any numerical value. While the second will maps any other URI (user/***/***) to corresponding user controller's methods. That means it automatically maps user/login to action_login(), user/register to action_register() and so on.
I would recommend you avoid using Route::controller() in this instance. While it can be fine to use in some cases, for what you're after it would be better to map to the routes.
You could do it like so.
Route::get('user', 'user#index');
Route::get('user/(:num)', 'user#profile');
Route::get('user/(:any)', 'user#(:1)');
Or you could be a little stricter with your last route.
Route::get('user/(login|logout)', 'user#(:1)');
My reasoning for recommending you avoid Route::controller() is that it does create duplicates to some content. For example, yoursite.com/user will by duplicated on yoursite.com/user/index. This can be bad for search engine optimization.
Mapping to your actions gives you that extra flexibility and control.
I want to use codeigniter for an ecommerce project I'm working on but I think I need some custom routing and I'm not sure if this is possible. I want to be able to use this url:
http://myecommsite.com/store/mens
By default in CI this would call the mens function in the store class. What I actually want is it to call a generic function in the store class and feed in 'mens' as a paremeter. The reason for this is that this site needs to have a mens,womens and childrens section.
Is this possible?
Also When I get further down the line...i.e
http://myecommsite.com/store/mens/category1/category2
how do I make Ci work with this?
Simply define a custom route in application/config/routes.php
Something like, for your url http://myecommsite.com/store/mens
$route['store/(:any)'] = "store/customfunction/$1";
This way all requests will be mapped to your "customfunction" method, which takes the parameter "mens"
You might also want to consdere the __remap() function, which overrides the methods (as opposed to the routing, which overrides the whole URI) Quoting from the manual:
If your controller contains a function named __remap(), it will always
get called regardless of what your URI contains. It overrides the
normal behavior in which the URI determines which function is called,
allowing you to define your own function routing rules.
So you can use a __remap() function in your controller store, and anything will be redirected to that. Any segments after the method name are passed into __remap() as second parameter, and you can use this array with call_user_func_array().
This could come in handy for your second examples of URI. Might be something like
function __remap('mymethod',$array = array())
{
return call_user_func_array('mymethod',$array);
}
and in your method "mymethod" you pick the array element and do what you need to do
If we use capital alphabet in between name for zend controller and action for example inside default module we create
class MyGoodController extends Zend_Controller_Action {
public fooBarAction()
{
}
}
Than to access this action browser url looks like mysite.com/my-good/foo-bar
Is there any default zend router added inside zf managing this translation ?
because I want to use URL view helper to generate the correct link for me which it doesnt for e.g in view
$this->url(array('action'=>'fooBar','controller=>'myGood'));
did not produce the correct url it generates /myGood/fooBar instead of /my-good/foo-bar
As stated in the comment you need to use:
$this->url(array('action'=>'foo-bar','controller=>'my-good'));
The URL view helper assembles a link based on a route set in your application.
Routes match requests based on the URL.
It really comes down to separation of concerns. The helper is only making use of a route and again routes only deal with what is in the URL. Getting the proper class names based on a route is the dispatcher's concerns.
It's best to leave the route to deal with only what is in the URL because dispatchers can change. What might work for you using the standard dispatcher may not fit others that use a different dispatcher.
To accomplish what you're asking, you can always use a custom view helper that does the conversion for you but that is assuming you never change dispatchers.