Reputation: 1895
I am working on designing a specific web framework that allows our team to add new components as plugins, then allowing customers to add these plugins or modules using a control panel. With CodeIgniter things were easy , just copy the controller into the controllers folder and the client-side module will find its way via the URL app/index.php/module/function But Laravel doesn't allow such dynamic routing.
Is there anyway to extend the route configuration without editing the routes.php by hand ?
Upvotes: 4
Views: 6890
Reputation: 6276
I know I'm bit late but in Laravel 5.4
we can achieve something like this:
Step 1 Create your package and create service provider in it.
Step 2 Register your package service provider in laravel config app.
Step 3 Now create a sperate routes service provider which will contain following
namespace MyPackage\Providers;
use App\Providers\RouteServiceProvider;
use Illuminate\Support\Facades\Route;
class MyPackageRouteServiceProvider extends RouteServiceProvider
{
protected $namespace='MyPackage\Controllers';
public function boot()
{
parent::boot();
}
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
}
protected function mapApiRoutes()
{
Route::prefix('Mypackage\api')
->middleware('api')
->namespace($this->namespace)
->group(__DIR__ . '\..\Routes\api.php');
}
protected function mapWebRoutes()
{
Route::prefix('Mypackage')
->middleware('web')
->namespace($this->namespace)
->group(__DIR__ . '\..\Routes\web.php');
}
}
Note: I'm considering there is Routes Folder
and contain web.php
and api.php
file. According to your question you want to load it dynamically you can have a constructor function and pass the package name, prefix and namespace as per your ease.
Step 4 Now the final step is registering the service provider you can call something like this in your package service provider:
public function boot()
{
$this->app->register('Mypackage\Providers\MyPackageRouteServiceProvider');
}
Hope this helps. Cheers
Upvotes: 2
Reputation: 5910
That's in fact pretty easy! When you think about it, Laravels routing layer is also just a component that is bound to Laravels container.
That allows us to grab it from there wherever we're accessing the container. Since you're trying to modify routes in a package, a great place to do it would be in your packages Service Provider.
Also, when doing that in a Service Provider you'll automatically have access to the app
property (Your service provider is a child class of Laravels ServiceProvider class) and you can grab the router pretty easy!
<?php namespace My\Packages\Namespace;
use Illuminate\Support\ServiceProvider;
class MyPackageProvider extends ServiceProvider {
public function boot()
{
$this->app['router']->get('package-route', function(){
return "I just dynamically registered a route out of my package";
});
}
}
That's the Service Provider of your package. The only thing the user will have to do is to add the Service Provider to his providers
array in the config/app.php
.
When a user has defined a route that is identically named as your dynamically added route, your route will be overwritten. Make sure that you're using some kind of route prefixes if you are dynamically adding routes.
Upvotes: 2
Reputation: 14202
You can simply add any routes you want in your service provider's 'boot' method:
public function boot()
{
$this->app['router']->get('my-route', 'MyVendor\Mypackage\MyController@action');
}
If you want to have a kind of automatic prefix, that doesn't happen automatically, but it's not too hard to create one:
public function boot()
{
$this->app['router']->group(['prefix' => 'my-module'], function ($router) {
$router->get('my-route', 'MyVendor\MyPackage\MyController@action');
$router->get('my-second-route', 'MyVendor\MyPackage\MyController@otherAction');
});
}
A lot of people will have this prefix as a config variable so that developers can choose the prefix they want (if you do this remember to name your routes so you can refer to them easily):
public function boot()
{
$this->app['router']->group(['prefix' => \Config::get('my-package::prefix')], function ($router) {
$router->get('my-route', 'MyVendor\MyPackage\MyController@action');
$router->get('my-second-route', 'MyVendor\MyPackage\MyController@otherAction');
});
}
Upvotes: 4