Installation:
composer require savannabits/filament-modules
Publish the config:
php artisan vendor:publish --provider="SavannaBits\FilamentModules\FilamentModulesServiceProvider"
Create a Module:
php artisan module:make ModuleName
This generates a module skeleton in Modules/ModuleName/ with:
ModuleServiceProvider (registers Filament resources/pages)Module.php (metadata)routes/web.php (module-specific routes)First Use Case:
Register a Filament resource in ModuleServiceProvider:
public function boot(): void
{
Filament::register(
\Modules\ModuleName\Resources\PostResource::class
);
}
Enable the module in config/filament-modules.php:
'enabled' => [
'ModuleName',
],
Modules/ directory (auto-generated by module:make).config/filament-modules.php (enable/disable modules, namespace settings).ModuleServiceProvider for Filament registrations.Modules/{Module}/routes/web.php.php artisan module:list, php artisan module:enable/disable.Modular Filament Resources:
Modules/{Module}/Resources/.ModuleServiceProvider:
public function boot(): void
{
if (Modules::isEnabled('ModuleName')) { // New check in v5.2.0
Filament::register(
\Modules\Blog\Resources\PostResource::class,
\Modules\Blog\Resources\PostResource\Pages\ManagePosts::class
);
}
}
Isolated Routes:
Modules/{Module}/routes/web.php:
Route::get('/blog/posts', [\Modules\Blog\Http\Controllers\PostController::class, 'index'])->name('blog.posts.index');
/blog/posts) for clarity.Shared Assets:
module-assets helper to publish assets:
$this->loadViewsFrom(__DIR__.'/Views', 'modules.blog');
$this->publishes([
__DIR__.'/Resources/views' => resource_path('views/vendor/modules/blog'),
], 'module-views');
Dependency Management:
composer.json:
"extra": {
"modules": {
"dependencies": ["another-module"]
}
}
config/filament-modules.php:
'dependencies' => [
'Blog' => ['Cms'],
],
Dynamic Module Loading:
Modules::enable() in a controller/middleware:
if (Modules::isEnabled('Blog')) { // New check in v5.2.0
Modules::enable('Blog');
}
Filament Panels:
ModuleServiceProvider:
public function boot(): void
{
if (Modules::isEnabled('Admin')) { // New check in v5.2.0
Filament::registerPanel(
\Modules\Admin\Filament\AdminPanel::class
);
}
}
Service Providers:
ModuleServiceProvider:
public function register(): void
{
if (Modules::isEnabled('Blog')) { // New check in v5.2.0
$this->app->bind(\Modules\Blog\Contracts\PostRepository::class, \Modules\Blog\Repositories\PostRepository::class);
}
}
Views:
@extends('modules.blog::layouts.app')
Testing:
Modules::fake();
Modules::shouldEnable('Blog');
Publishing Assets:
module:publish command:
php artisan module:publish ModuleName --tag=config,views,assets
Namespace Conflicts:
Module.php match the directory structure:
protected $namespace = 'Modules\\Blog';
composer dump-autoload after renaming modules.Route Caching:
php artisan route:clear
php artisan route:list to debug missing routes.Filament Panel Registration:
ModuleServiceProvider:
public function boot(): void {
if (Modules::isEnabled('Admin')) { // New check in v5.2.0
Filament::registerPanel(AdminPanel::class); // First!
}
Filament::register(PostResource::class);
}
Module Dependencies:
module:list --tree to visualize:
php artisan module:list --tree
Asset Compilation:
npm run dev or npm run build in the module’s directory:
cd Modules/Blog && npm run dev
Module Provider Registration Check:
ModuleServiceProvider uses Modules::isEnabled() to avoid errors.Module Not Loading:
config/filament-modules.php for enabled modules.ModuleServiceProvider is registered in config/app.php.Modules::isEnabled('ModuleName') returns true before registration.Filament Resources Missing:
ModuleServiceProvider only if the module is enabled:
if (Modules::isEnabled('Blog')) { // New check in v5.2.0
Filament::register(PostResource::class);
}
Routes Not Found:
php artisan route:list and filter by module prefix.Modules/{Module}/routes/web.php.Views Not Found:
@extends directives.php artisan view:clear if views are cached.Module Metadata:
Module.php:
protected $description = 'Handles blog posts and comments';
protected $author = 'Your Name';
Environment-Specific Modules:
config/filament-modules.php:
'enabled' => env('APP_ENV') === 'local' ? ['Blog', 'Cms'] : ['Blog'],
Module Commands:
ModuleCommand:
use SavannaBits\FilamentModules\Console\ModuleCommand;
class BlogCommand extends ModuleCommand {
protected $signature = 'blog:seed';
// ...
}
Testing Modules:
Modules::fake() to isolate module tests:
public function test_module_isolation() {
Modules::fake();
Modules::shouldEnable('Blog');
$this->get('/blog/posts')->assertOk();
}
Performance:
config/filament-modules.php to reduce autoload overhead.Modules::disable('UnusedModule') dynamically in production.Extending Core Modules:
php artisan module:publish Blog --tag=config
ModuleServiceProvider in your app’s AppServiceProvider.Localization:
Modules/{Module}/Resources/lang/.ModuleServiceProvider:
public function boot(): void
{
if (Modules::isEnabled('Blog')) { // New check in v5.2.0
$this->loadTranslationsFrom(__DIR__.'/Resources/lang', 'modules.blog');
}
}
**Namespace Retrie
How can I help you explore Laravel packages today?