artificertech/filament-multi-context
Installation:
composer require artificertech/filament-multi-context
php artisan vendor:publish --provider="ArtificerTech\FilamentMultiContext\FilamentMultiContextServiceProvider" --tag="filament-multi-context-config"
Publish the config file to customize default behavior.
Create a Context:
php artisan make:filament-context [ContextName]
Example: php artisan make:filament-context AdminDashboard
Register Context:
Add the context to config/filament-multi-context.php under the contexts array:
'contexts' => [
'admin' => [
'class' => \App\FilamentAdmin\FilamentAdminContext::class,
'label' => 'Admin Panel',
'icon' => 'heroicon-o-home',
'active' => true,
],
],
First Use Case:
Access the new context by navigating to /admin (or your configured path). The context will include its own resources, pages, and widgets, isolated from other contexts.
Context Isolation:
FilamentTeams, FilamentAdmin, etc.) operates independently with its own:
app/[ContextName]/Resources/).app/[ContextName]/Pages/).app/[ContextName]/Widgets/).Admin, TeamLeads, Support).Dynamic Context Switching:
FilamentMultiContextServiceProvider's boot() method to dynamically register contexts:
public function boot()
{
$this->registerContexts([
'admin' => \App\FilamentAdmin\FilamentAdminContext::class,
'team' => \App\FilamentTeams\FilamentTeamsContext::class,
]);
}
Shared vs. Isolated Assets:
app/Providers/FilamentServiceProvider) in the root app/Providers/ to apply across all contexts.app/FilamentTeams/Resources/UserResource) within the context directory.Middleware Integration:
namespace App\FilamentTeams;
use ArtificerTech\FilamentMultiContext\Contracts\FilamentContext;
use Illuminate\Support\Facades\Gate;
class FilamentTeamsContext implements FilamentContext
{
public function getMiddleware(): array
{
return [
\App\Http\Middleware\CheckTeamAccess::class,
];
}
}
Context-Specific Routes:
context() helper to generate URLs for resources/pages within a context:
route('filament.admin.resources.users.index'); // Admin context
route('filament.team.resources.projects.index'); // Team context
Widget and Page Sharing:
use \App\Widgets\SharedWidget; in context-specific widgets).Multi-Tenant Admin Panels:
Tenant::all()->each(function ($tenant) {
$this->registerContexts([
"tenant-{$tenant->id}" => \App\FilamentTenants\FilamentTenantContext::class,
]);
});
Role-Based Access:
'contexts' => [
'admin' => [
'class' => \App\FilamentAdmin\FilamentAdminContext::class,
'active' => auth()->user()->isAdmin(),
],
],
Context-Specific Notifications:
getNotifications() method in the context class to show context-relevant alerts.Testing:
actingAs() with context-specific users:
$this->actingAs($adminUser)
->get('/admin/resources/users')
->assertStatus(200);
$this->actingAs($teamUser)
->get('/team/resources/projects')
->assertStatus(200);
Namespace Conflicts:
App\FilamentTeams\FilamentTeamsContext vs. App\FilamentAdmin\FilamentAdminContext).Resource).Asset Loading Issues:
active in the config.app/[ContextName] directory exists and is autoloaded (check composer.json).config/filament-multi-context.php.Middleware Overrides:
// Ensure this runs AFTER Filament's middleware in app/Http/Kernel.php
'web' => [
// ...
\App\Http\Middleware\CheckTeamAccess::class,
],
Cached Views:
php artisan filament:cache-reset
Database Seeding:
public function run()
{
$this->call([
\Database\Seeders\FilamentAdmin\AdminUsersTableSeeder::class,
\Database\Seeders\FilamentTeams\TeamProjectsTableSeeder::class,
]);
}
Context Not Loading:
filament-multi-context log channel for registration errors:
\Log::channel('filament-multi-context')->debug('Context registered');
filament-multi-context:contexts config array.Routes Missing:
php artisan route:list to confirm context routes are registered. If missing, check:
getRoutes() method (if overridden).filament-multi-context service provider is registered in config/app.php.Blade Template Errors:
resources/views/filament/[context]/...) are properly namespaced:
@extends('filament::base')
@section('title', __('Filament Teams'))
Context-Specific Config:
getConfig() method in the context class to override Filament settings:
public function getConfig(): array
{
return [
'panel' => [
'path' => 'team',
'brandName' => 'Team Portal',
],
];
}
Dynamic Context Registration:
event(Registered::class, function (Registered $event) {
if ($event->user->isTeamLead()) {
app(\ArtificerTech\FilamentMultiContext\FilamentMultiContextServiceProvider::class)
->registerContexts([
'team-lead' => \App\FilamentTeamLeads\FilamentTeamLeadsContext::class,
]);
}
});
Shared Authentication:
getAuthentication() method:
public function getAuthentication(): array
{
return [
\App\Providers\FilamentAuthProvider::class,
];
}
Performance:
public function boot()
{
if (app()->runningInConsole()) {
return;
}
$this->registerContexts([...]);
}
Extending the Package:
filament-multi-context config:
'context_types' => [
'default' => \ArtificerTech\FilamentMultiContext\Contracts\FilamentContext::class,
'tenant' => \App\Contracts\TenantFilamentContext::class,
],
How can I help you explore Laravel packages today?