Extend Laravel Modular with custom plugins that discover and register module resources
The plugin system is Laravel Modular’s extensibility mechanism that allows you to discover and register module resources automatically. Plugins are classes that implement a discovery pattern to find resources across all modules and handle their registration with Laravel.
Here’s how to create a custom plugin that discovers and registers custom resources.
1
Create the Plugin Class
2
Extend the base Plugin class:
3
use InterNACHI\Modular\Plugins\Plugin;use InterNACHI\Modular\Support\FinderFactory;use Illuminate\Support\Collection;class CustomPlugin extends Plugin{ public function discover(FinderFactory $finders): iterable { // Return discovered resources } public function handle(Collection $data): void { // Register resources with Laravel }}
4
Implement Discovery Logic
5
Use the FinderFactory to locate resources across modules:
6
public function discover(FinderFactory $finders): iterable{ return $finders ->commandFileFinder() // Built-in finder for commands ->withModuleInfo() ->values() ->map(fn(ModuleFileInfo $file) => $file->fullyQualifiedClassName()) ->filter($this->isValid(...));}
7
Implement Handling Logic
8
Register discovered resources with Laravel services:
9
public function handle(Collection $data): void{ $data->each(function(string $class) { // Register with Laravel service app()->singleton($class); });}
10
Register Your Plugin
11
Add your plugin to the registry in a service provider:
12
use InterNACHI\Modular\PluginRegistry;public function boot(){ PluginRegistry::register(CustomPlugin::class);}
The PluginRegistry manages plugin registration and resolution:
use InterNACHI\Modular\PluginRegistry;// Register pluginsPluginRegistry::register( CustomPlugin::class, AnotherPlugin::class);// Get a plugin instance$plugin = app(PluginRegistry::class)->get(CustomPlugin::class);
Source: src/PluginRegistry.php:14-32
Plugins are resolved as singletons from the Laravel container, so they can inject dependencies through their constructors.
Idempotency: Ensure your plugin’s handle() method can be called multiple times safely.
Performance: Use the appropriate finder methods to minimize filesystem scanning. The FinderFactory methods are optimized for specific directory structures.
Error Handling: Handle cases where resources might not exist or be malformed gracefully.
Plugins boot during the application’s boot phase. Avoid heavy operations in plugin constructors or discovery methods that could slow down application startup.