Laravel: Optional route prefix parameter - php

I'm currently working on a multi-site application (one codebase for multiple (sub)sites) and I would love to leverage route caching, but currently I'm hardcoding a prefix instead of dynamically determining it.
When trying to do this I'm running into an issue which I've illustrated below:
Route::group(['prefix' => '{subsite}', 'subdomain' => '{site}.domain.tld'], function () {
Route::get('blog', 'BlogController#index')->name('blog.index');
});
When accessing a subsite like http://sitename.domain.tld/subsitename/blog this all works fine, but it doesn't work anymore when not accessing a subsite like http://sitename.domain.tld/blog, as it will now think that the prefix is 'blog'.
Is there any way to allow the 'subsite' parameter to be empty or skipped?
Thanks!

As far as I know there isn't anything in the current routing system that would allow you to solve your problem with a single route group.
While this doesn't answer your specific question, I can think of two ways that you could implement your expected behaviour.
1. Duplicate the route group
Route::group(['subdomain' => '{site}.domain.tld'], function () {
Route::get('blog', 'BlogController#index')->name('blog.index');
});
Route::group(['prefix' => '{subsite}', 'subdomain' => '{site}.domain.tld'], function () {
Route::get('blog', 'BlogController#index')->name('blog.index');
});
2. Loop through an array of expected prefixes.
$prefixes = ['', 'subsiteone', 'subsitetwo'];
foreach($prefixes as $prefix) {
Route::group(['prefix' => $prefix, 'subdomain' => '{site}.domain.tld'], function () {
Route::get('blog', 'BlogController#index')->name('blog.index');
});
}

Related

How to set name in route group in laravel 5.5?

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.');

How to group similar Laravel routes using the same controller?

I want to pretty-up my routes, ie, I have such entries:
// DataTable
Route::get('dt/reservations/{room_id]', 'DataTablesController#reservations')->where(['room_id', '[0-9]+']);
Route::get('dt/rooms/{area_id]', 'DataTablesController#rooms')->where(['area_id', '[0-9]+']);
Route::get('dt/departments', 'DataTablesController#departments');
Route::get('dt/addresses', 'DataTablesController#areas');
Route::get('dt/areas', 'DataTablesController#areas');
I would like to make it more understandable. I can add prefix what would give me:
// DataTable
Route::group(['prefix' => 'dt'], function () {
Route::get('reservations/{room_id]', 'DataTablesController#reservations')->where(['room_id', '[0-9]+']);
Route::get('rooms/{area_id]', 'DataTablesController#rooms')->where(['area_id', '[0-9]+']);
Route::get('departments', 'DataTablesController#departments');
Route::get('addresses', 'DataTablesController#areas');
Route::get('areas', 'DataTablesController#areas');
});
But can I somehow make the rest too? The route name and method name will always be the same.
Is it possible to make something like:
// DataTable
Route::group(['prefix' => 'dt'], function () {
Controller => DataTablesController,
Methods => [
'reservations',
'rooms',
'departments',
'addresses',
'areas'
];
});
Although a very good feature. But it can't be done in Laravel
All your routes must be explicit, Laravel won't/can't assume that you
are using same controller for all the routes.
So you will have to define all the routes explicitly.
Only Resource Controllers can have implicit routing in Laravel
Take a look here....
Route use the same controller

Laravel Route redirecting to the right controller when using parameters [architecture]

So building a few pages on the same template and loading the content via AJAX. Most of the content are forms. Views are defined by step number (1,2,3,4,5....32)
Here is how I built my route:
Route::get('onboarding/', [
'as' => 'get-onboarding-start',
'uses' => 'OnboardingController#getStart'
]);
Route::get('onboarding/{i}', [
'as' => 'get-onboarding-step',
'uses' => 'OnboardingController#getNextStep'
]);
Route::post('onboarding/{i}', [
'as' => 'post-onboarding-step',
'uses' => 'OnboardingController#postStepForm'
]);
Now one method in the controller cannot handle all the work. Meaning I will need to redirect to another method based on the $i (step number).
I am afraid that it is not simple to read if I put a big blog of switch case $i = 1,2,3...
At the same time I don't want to write 32 different routes.
What would you propose?
Hard code all the routes meaning: 'onboarding/username' then
'onboarding/email' etc... etc... The good point is that it is super
simple to read in the views and you know exactly what the next step
is... no need to check what the number corresponds to.
Catch all as coded now and redirect to different methods in the controller
Something better, super easy to read and with little lines of
code... which is .... ??
If these steps are going to remain as they are without many changes in the future, I'd go for the first option (having 32 get & 32 post routes). This will keep your application simple, if you'd want to apply parameters or middleware to them you can use route groups. Below I've posted a small code example from the laravel documentation
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () {
// Uses Auth Middleware
});
Route::get('user/profile', function () {
// Uses Auth Middleware
});
});

Laravel dynamic URL routing

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.

Laravel group admin routes

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');
});
});

Categories