When defining a route in Laravel 4 is it possible to define multiple URI paths within the same route?
presently i do the following:
Route::get('/', 'DashboardController#index');
Route::get('/dashboard', array('as' => 'dashboard', 'uses' => 'v1\DashboardController#index'));
but this defeats my purpose, i would like to do something like
Route::get('/, /dashboard', array('as' => 'dashboard', 'uses' => 'DashboardController#index'));
I believe you need to use an optional parameter with a regular expression:
Route::get('/{name}', array(
'as' => 'dashboard',
'uses' => 'DashboardController#index')
)->where('name', '(dashboard)?');
* Assuming you want to route to the same controller which is not entirely clear from the question.
* The current accepted answer matches everything not just / OR /dashboard.
I find it interesting for curiosity sake to attempt to solve this question posted by #Alex as a comment under #graemec's answer to post a solution that works:
Route::get('/{name}', [
'as' => 'dashboard',
'uses' => 'DashboardController#index'
]
)->where('name', 'home|dashboard|'); //add as many as possible separated by |
Because the second argument of where() expects regular expressions so we can assign it to match exactly any of those separated by | so my initial thought of proposing a whereIn() into Laravel route is resolved by this solution.
PS:This example is tested on Laravel 5.4.30
Hope someone finds it useful
If I understand your question right I'd say:
Use Route Prefixing: http://laravel.com/docs/routing#route-prefixing
Or (Optional) Route Parameters: http://laravel.com/docs/routing#route-parameters
So for example:
Route::group(array('prefix' => '/'), function() { Route::get('dashboard', 'DashboardController#index'); });
OR
Route::get('/{dashboard?}', array('as' => 'dashboard', 'uses' => 'DashboardController#index'));
Related
I have made two routes:
Single tour route:
Route::get('{category}/{slug}',
['as' => 'single.tour',
'uses' => 'PublicController#singleTour'])
->where('category', '[A-Za-z\d\-\_]+')
->where('slug', '[A-Za-z\d\-\_]+');
Travel guide route:
Route::get('{pcategory}/{slug}',
['as' => 'travel-guide',
'uses' => 'PublicController#getTravelguide'])
->where('pcategory', '[A-Za-z\d\-\_]+')
->where('slug', '[A-Za-z\d\-\_]+');
both with Regular Expression Constraints but still the second route travel-guide is being redirected to view of first route single.tour. I tried replacing {travel-guide} with travel-guide [static] but still getting same problem. Though I found solution [worst idea] the solution by attaching any extensions like (php,html,jsp,aspx,css....etc) to the url example below:
Route::get('{pcategory}/{slug}.php',
['as' => 'travel-guide',
'uses' => 'PublicController#getTravelguide'])
->where('pcategory', '[A-Za-z\d\-\_]+')
->where('slug', '[A-Za-z\d\-\_]+');
It works well returning its own view. But this is not the best solution. Can anyone suggest me solution to this problem ?
Consider the following:
Route::get('/', ['as' => 'home.index', 'uses' => 'HomeController#index']);
Route::group(['domain' => 'thechildandthepoet' . env('CONNECTION')], function() {
Route::get('/', ['as' => 'thechildandthepoet.home', 'uses' => 'GameController#index']);
});
When I go to thechildandthepoet.example.local It shows me the contents of
Route::get('/', ['as' => 'home.index', 'uses' => 'HomeController#index']);
completely by passing the fact that I told it which controller to use.
The link looks like: <li>The Child And The Poet</li>
any idea why this doesn't work?
Laravel's router executes the first route that matches given URL.
You don't specify the domain for your first route, therefore it matches all domains. The second route, even though it matches the URL as well, is ignored.
Reorganize your routes.php file, put the routes that specify the domain at the beginning and keep the most generic routes at the end.
I'm doing a simple project. I want it to be as minimal as possible so I tried to create system where I can create pages and they're placed at localhost/{page?}
But, here's the problem. I also want some routes to be defined (e.g. route /blog) like below.
Route::get('/{page?}', ['as' => 'root', 'uses' => 'SiteController#getRoot']);
Route::get('blog/{slug?}', ['as' => 'blog.post', 'uses' => 'BlogController#getPost']);
Route::get('blog/page/{page}', ['as' => 'blog.page', 'uses' => 'BlogController#getPage'])->where('page', '[0-9]+');
With this setup, it only uses the first route.
My question is. Is there a way to do this? Or, is this beyond capabilities of Laravel?
Thank you for any help.
Yeah, place your first route as the last route. That way it will get picked up last. You may also need to place the blog/{slug?} before that one as well so blog/slug/{page} is first.
Route::get('blog/page/{page}', ['as' => 'blog.page', 'uses' => 'BlogController#getPage'])->where('page', '[0-9]+');
Route::get('blog/{slug?}', ['as' => 'blog.post', 'uses' => 'BlogController#getPost']);
Route::get('/{page?}', ['as' => 'root', 'uses' => 'SiteController#getRoot']);
Basically what happens is the most basic route is picking up the other routes because there is no reason for it not to and it technically matches the route even though it's not the route you want. Putting the most specific routes first usually handles this issue.
Try reordering them:
Route::get('blog/page/{page}', ['as' => 'blog.page', 'uses' => 'BlogController#getPage'])->where('page', '[0-9]+');
Route::get('blog/{slug?}', ['as' => 'blog.post', 'uses' => 'BlogController#getPost']);
Route::get('/{page?}', ['as' => 'root', 'uses' => 'SiteController#getRoot']);
otherwise they get "overwritten"
Let's say I have 2 urls:
localhost/backend/admin
localhost/backend/admin/users
In my routes.php, I would have a route that looks like this:
Route::group(array('prefix' => 'backend', 'before' => 'auth'), function(){
// Some methods I have on this controller are: getIndex, postUpdate, etc...
Route::controller('admin', 'AppBackend\Controllers\Admin\AdminController');
// Some methods I have on this controller are: getIndex, postUpdate, etc...
Route::controller('admin/users', 'AppBackend\Controllers\Admin\Users\UsersController');
});
The problem is that when I enter admin/users into the browser, Laravel thinks that I'm trying to call a method on the AdminController and finds it doesn't exist among the methods I have for this controller. It seems it would be more ideal, if a method is not found, for Laravel to continue down the routes file and hit my admin/users route and call UsersController.
2 Possible solution that I'm not fully satisfied with:
Reverse the order of the routes. This won't read as naturally as I would like it to, from top to bottom. Plus, I don't know how this solution will hold up over time with every case I have in the future.
Switch to using resource routes. I don't like using PUT/DELETE when it's not supported by some browsers. I like having my own set of action words (and simply renaming and adding to the default resources is not enough or becomes clunky). See also What is the value of using PUT/DELETE with Laravel?
Are there any other good solutions?
The best way of doing routes until now is to make them all manually one by one. In this article Phil Sturgeon pushed me to start to do that and I finally realized that I was having too much trouble using resourceful and restful for a little gain.
It's better to have control of your route listing. Resourceful controllers add too much info, like route parameters, and, to make resourceful controllers not create a bunch of routes I don't use I have to filter what should be generated. In the end it was simply easier to create one route every time I was creating a functionality on my application.
As far as I can tell, to process all your routes in the correct order, Laravel builds a list of your routes, exactly the same way if we were doing it manually. So, there is no performance penalty in doing them manually.
This is an example of my routes in an application I'm just starting:
// Firewall Blacklisted IPs blocked from all routes
Route::group(['before' => 'fw-block-bl'], function()
{
Route::group(['namespace' => 'Application\Controllers'], function()
{
// Pretty error message goes to this route
Route::get('error', ['as' => 'error', 'uses' => 'Error#show']);
Route::get('coming/soon', ['as' => 'coming.soon', 'uses' => 'ComingSoon#index']);
Route::post('coming/soon', ['as' => 'coming.soon.post', 'uses' => 'ComingSoon#register']);
Route::get('coming/soon/register', ['as' => 'coming.soon.register', 'uses' => 'ComingSoon#register']);
Route::post('coming/soon/audit', ['as' => 'coming.soon.audit', 'uses' => 'ComingSoon#audit']);
Route::get('coming/soon/activate/{code}', ['as' => 'coming.soon.activate', 'uses' => 'ComingSoon#activate']);
// Whitelisted on firewall will have access to those routes,
// otherwise will be redirected to the coming/soon page
Route::group(['before' => 'fw-allow-wl'], function()
{
Route::get('user/activate/{code}', ['as' => 'user/activate', 'uses' => 'User#activate']);
Route::get('user/activation/send/{email?}', ['as' => 'user/activation', 'uses' => 'User#sendActivation']);
Route::get('login', ['as' => 'login', 'uses' => 'Logon#loginForm']);
Route::post('login', ['as' => 'login', 'uses' => 'Logon#doLogin']);
Route::get('logout', ['as' => 'logout', 'uses' => 'Logon#doLogout']);
Route::get('register', ['as' => 'register', 'uses' => 'Register#registerForm']);
Route::get('user/recoverPassword/{code}', ['as' => 'user/recoverPassword', 'uses' => 'User#recoverPassword']);
Route::post('user/changePassword', ['as' => 'user/changePassword', 'uses' => 'User#changePassword']);
// Must be authenticated
Route::group(['before' => 'auth'], function()
{
Route::get('/', ['as' => 'home', 'uses' => 'Home#index']);
Route::get('profile', ['as' => 'profile', 'uses' => 'User#profile']);
Route::group(['prefix' => 'offices'], function()
{
Route::get('/', ['uses' => 'Offices#index']);
Route::get('create', ['uses' => 'Offices#create']);
});
Route::group(['prefix' => 'users'], function()
{
Route::get('/', ['uses' => 'Users#index']);
Route::get('create', ['uses' => 'Users#create']);
});
});
});
});
});
All controllers will be namespaced in Application\Controllers and all methods (or subroutes) are prefixed.
EDIT
I'm starting to think I dont name my routes too, I'm not really using them, but I'm still not certain of this, so routes names are not really clear in this raw example. Some also have a 'uses' that could be removed and they will as soon as I decide myself by using names or not.
EDIT 2
I don't do ->before() in routes, because I like to read my routes files sometimes and this method may only be visible after a big list of routes.
How do you add an regexp on a Route::group? On a normal Route::verb you add ->where('segment', 'regex') to the end, but how do you do it on a group?
I would like something like this (not working as ->where() on Route::group is invalid):
Route::group(['prefix' => '{profileId}'], function(){
Route::get('/', [
'as' => 'profileShow',
'uses' => 'ProfileController#getShow'
]);
Route::post('ny-anvandare', [
'as' => 'profileAccessNew',
'uses' => 'ProfileController#getAccess'
]);
})->where('profileId', '[0-9]+');
You'll need to use the Enhanced Router package by Jason Lewis: https://github.com/jasonlewis/enhanced-router
It introduces much requested enhancements to Laravel's Routing components, including regex filters on groups.
I am not 100% sure if it is Laravel 4.1-ready, but if you're using 4.0, you should be good to go.