Is there a way to cleanly group all routes starting with admin/?
I tried something like this, but it didn't work ofcourse:
Route::group('admin', function()
{
Route::get('something', array('uses' => 'mycontroller#index'));
Route::get('another', array('uses' => 'mycontroller#second'));
Route::get('foo', array('uses' => 'mycontroller#bar'));
});
Corresponding to these routes:
admin/something
admin/another
admin/foo
I can ofcourse just prefix all those routes directly with admin/, but I'd like to know if it's possible to do it my way.
Thanks!
Unfortunately no. Route groups were not designed to work like that. This is taken from the Laravel docs.
Route groups allow you to attach a set of attributes to a group of routes, allowing you to keep your code neat and tidy.
A route group is used for applying one or more filters to a group of routes. What you're looking for is bundles!
Introducing Bundles!
Bundles are what you're after, by the looks of things. Create a new bundle called 'admin' in your bundles directory and register it in your application/bundles.php file as something like this:
'admin' => array(
'handles' => 'admin'
)
The handles key allows you to change what URI the bundle will respond to. So in this case any calls to admin will be run through that bundle. Then in your new bundle create a routes.php file and you can register the handler using the (:bundle) placeholder.
// Inside your bundles routes.php file.
Route::get('(:bundle)', function()
{
return 'This is the admin home page.';
});
Route::get('(:bundle)/users', function()
{
return 'This responds to yoursite.com/admin/users';
});
Hope that gives you some ideas.
In Laravel 4 you can now use prefix:
Route::group(['prefix' => 'admin'], function() {
Route::get('something', 'mycontroller#index');
Route::get('another', function() {
return 'Another routing';
});
Route::get('foo', function() {
return Response::make('BARRRRR', 200);
});
Route::get('bazz', function() {
return View::make('bazztemplate');
});
});
Related
I am just getting started with Laravel and find the route setup a little confusing. I am trying to create a few pages, that ultimately should have the struture:
domain.com/onboarding
domain.com/onboarding/skip
domain.com/onboarding/skip/anothersubview
etc.
Right now I have:
// Registered and Activated User Routes
Route::group(['middleware' => ['auth', 'activated', 'activity']], function () {
Route::get('/onboarding', 'UserController#Onboarding')->name('onboarding');
});
Would the solution here (and best practice) be to just add another route inside my Route::group, like:
Route::view('/onboarding/skip', 'onboarding.skip');
Is this the correct way of doing things?
use prefix :
Route::group(['prefix' => 'onboarding','middleware' => ['auth', 'activated', 'activity']], function () {
Route::get('/', 'UserController#Onboarding')->name('onboarding');
Route::get('/skip', 'UserController#OnboardingSkip')->name('onboarding_skip');
Route::get('/skip/anothersubview', 'UserController#OnboardingSkipSubview')->name('onboarding_skipsubview');
});
read more here : https://laravel.com/docs/5.6/routing
The structure I used in a few projects in the past looks like this:
Route::group(['prefix' => 'onboarding'], function(){
Route::group(['prefix' => 'something'], function(){
Route::get('/', function(){}); //onboarding/something
Route::group(['prefix' => 'somethingelse'], function(){
Route::get('/', function(){}); //onboarding/something/somethingelse
Route::get('/{id}', function(){}); //onboarding/something/somethingelse/15
});
});
});
nesting groups can help you make the easier extendable router because when you realize you need to add some URL in the middle of long structure it would be easier to do it with this concept
You have a web.php file in your routes folder, there you need to add:
Route::get('/subpage', 'controllername#function-name-you-want-to-call');
Hope this helps, if it doesn't let me know
/e: to clarify:
the first part
Route::group(['middleware' => ['auth', 'activated', 'activity']], function () {
is the authentication. Depending on who you want to access this page, you might not need it
I'm using this package in my project and there have default package routes.
Like this:
I want use this route in my controller. I'm trying to use with name but it did not work this way.
Route::group(['prefix' => 'admin', 'as' => 'admin.'], function () {
Voyager::routes();
});
And
Route::group(['prefix' => 'admin'], function () {
Voyager::routes();
})->name('admin');
I'm trying to use like this:
I want to give access like this, as if I'm trying to access 'admin' route then I could access all routes under these route group. I don't know how I will do that?
Please help me.
You cannot redirect to route with name admin. because such route doesn't exist.
When you use:
Route::group(['prefix' => 'admin', 'as' => 'admin.'], function () {
Voyager::routes();
});
it means all routes created by Voager::routes() will have name starting with admin. but it doesn't mean admin. route exist.
So I assume you should instead use rather admin.voyager.dashboard instead, so you should rather use:
return redirect()->route('admin.voyager.dashboard');
instead of:
return redirect()->route('admin.');
I am relatively new with Laravel and taking it on myself to learn some new technologies and platforms. I am loving Laravel's routing features and just wondering if there was a way to route to resources within a route group dynamically.
Route::group(['domain' => 'api.domain.dev', 'prefix' => '/{version}/{resource}'],
function ($ignore, $version = 'v1', $resource = 'test') {
// Check if resource exists, if not 404
$path = '../app/Http/Controllers/api/'.$version.'/'.$resource.'Controller.php';
if (!File::exists($path)) {
abort(404);
}
// Add magic method __get to handle errors and use interface to ensure all methods are available
Route::get('', "api\\{$version}\\{$resource}Controller#index");
Route::put('', "api\\{$version}\\{$resource}Controller#put");
Route::post('', "api\\{$version}\\{$resource}Controller#post");
Route::delete('', "api\\{$version}\\{$resource}Controller#delete");
}
);
Essentially what I am trying to achieve is to route all API subdomains into a group. Then use a version number to route to a group of controllers dynamically, these will be split by folder name.
Example URL
http://api.domain.com/v1/test
To create dynamic URL routing in Laravel with versioning, namespaces, and prefixes, you can use the group method in your routes/api.php file.
Route::middleware(APIversion::class)->prefix('{version}/{device}')->group(function () {
Route::group(['namespace' => 'Api\\'.request()->route('version').'\\'], function () {
Route::controller(AuthController::class)->group(function(){
Route::post('/login',['as' => 'login', 'uses' => 'login']);
});
});
});
That should work.
I was reading laravel 5.1 documentation. I didn't understand how laravel route group working and what's the difference between following route groups.
Route Groups & Named Routes
If you are using route groups, you may specify an as keyword in the route group attribute array, allowing you to set a common route name prefix for all routes within the group:
Route::group(['as' => 'admin::'], function () {
Route::get('dashboard', ['as' => 'dashboard', function () {
// Route named "admin::dashboard"
}]);
});
Middleware
To assign middleware to all routes within a group, you may use the middleware key in the group attribute array. Middleware will be executed in the order you define this array:
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () {
// Uses Auth Middleware
});
Route::get('user/profile', function () {
// Uses Auth Middleware
});
});
Namespaces
Another common use-case for route groups is assigning the same PHP namespace to a group of controllers. You may use the namespace parameter in your group attribute array to specify the namespace for all controllers within the group:
Route::group(['namespace' => 'Admin'], function()
{
// Controllers Within The "App\Http\Controllers\Admin" Namespace
Route::group(['namespace' => 'User'], function()
{
// Controllers Within The "App\Http\Controllers\Admin\User" Namespace
});
});
Sub-Domain Routing
Route groups may also be used to route wildcard sub-domains. Sub-domains may be assigned route parameters just like route URIs, allowing you to capture a portion of the sub-domain for usage in your route or controller. The sub-domain may be specified using the domain key on the group attribute array:
Route::group(['domain' => '{account}.myapp.com'], function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});
Route Prefixes
The prefix group array attribute may be used to prefix each route in the group with a given URI. For example, you may want to prefix all route URIs within the group with admin:
Route::group(['prefix' => 'admin'], function () {
Route::get('users', function () {
// Matches The "/admin/users" URL
});
});
You may also use the prefix parameter to specify common parameters for your grouped routes:
Route::group(['prefix' => 'accounts/{account_id}'], function () {
Route::get('detail', function ($account_id) {
// Matches The accounts/{account_id}/detail URL
});
});
Ref: http://laravel.com/docs/5.1/routing
Route groups allow you to group together routes that share common attributes without having to redefine said attributes for each route.
Example
As an example lets use the namespace array attribute.
Say we have a controller called NewsController that contains all the Admin logic for your apps news section. You may place this file within the 'App/Http/Controllers/Admin` directory.
Laravel 5 follows PSR-4 autoloading conventions, so the application expcets the namespace to be identical to the path of the file, so our class might look something like this:
<?php
namespace App\Http\Controllers\Admin;
class NewsController
{
}
We could write a route to this class like so:
Route::get('admin/news', [
'uses' => 'Admin\NewsController#index'
]);
Note: Laravel automatically assumes all your controllers will be in the App/Http/Controllers directory so we can leave this out of any controller declarations in the routes file.
The above should work fine, but maybe you also have a dozen or so other class files that deal with Admin logic all within the same namespace. We can use the namespace option to group these together.
Route::group(['namespace' => 'Admin'], function()
{
Route::get('admin/news', [
'uses' => 'NewsController#index'
]);
Route::get('admin/users', [
'uses' => 'UserController#index'
]);
...
});
Notice how I no longer define the Admin namespace for the controller for each route.
The same process can be applied to middleware, subdomains, and url prefixes.
Further Example
Lets take the first example and build on it. As you can see from the above route declarations all our admin routes share a common url prefix.
http://example.com/admin/news
http://example.com/admin/users
We can use the prefix array attribute to define the common url for our routes. In our case this is admin.
Our updated Route declarations would look like so.
Route::group(['namespace' => 'Admin', 'prefix' => 'admin'], function()
{
Route::get('news', [
'uses' => 'NewsController#index'
]);
Route::get('users', [
'uses' => 'UserController#index'
]);
...
});
Your probably wondering why would this be useful? Well imagine you have developed a large application with tens if not hundreds of routes. Then one day your boss comes to you and says "Hey Mr. tester, we need to change the admin url from /admin to /cms, how long will this take?".
If you've declared all your routes using groups with the prefix array attribute like above, this is going to be an easy and painless process for you.
I have a route defined as:
Route::resource('item', 'ItemController');
What I want to do is put some of these routes, particularly edit and delete inside a group.
Route::group(['middleware' => ['role']], function() {
Route::resource('item', 'ItemController', ['only' => ['edit', 'delete']]);
}
This doesn't work, though. Do I have to define each route one by one then? Or is there a better solution to this?
EDIT:
I'm sorry, but it seems I did not ask the question properly. So let me make some clarifications here.
I have a basic auth user which can create and view items. What I don't want it to do is edit and delete.
I then also have a role user which do everything auth can do AND edit and delete items.
So basically, regular authorized users can have SOME access to items while role users have COMPLETE access.
The current code seems to give role users ONLY edit and delete functionalities and no view or create.
To make it even more clearer, here's what my actual route looks like:
Route::group(['middleware' => ['auth']], function()
{
Route::resource('items', 'SitesController');
Route::group(['middleware' => ['role']], function() {
Route::resource('item', 'ItemController', ['only' => ['edit', 'delete']]);
});
});
Maybe I'm going about this the wrong way?
The code above will work, you just named the action incorrectly. You should have used destroy instead of delete. Try the following code:
Route::resource('item', 'ItemController');
Route::group(['middleware' => ['role']], function() {
Route::resource('item', 'ItemController', ['only' => ['edit', 'destroy']]);
});
You can run php artisan route:list to verify. You should see role middleware enabled in 2 of your routes.