Resource Contributions
Capell’s admin panel uses admin surface contributions to expose resources, pages, widgets, panel extenders, and related admin UI additions through one registry.
Resources
Section titled “Resources”Resources are Filament resource classes that provide admin panel functionality for a given model type. Capell uses resource contributions to:
- Link media to models.
- Navigate from dashboards and reports to resource pages.
- Let add-on packages expose admin screens without patching the panel directly.
Resource Groups And Names
Section titled “Resource Groups And Names”Resources are grouped by model or admin concept, with an optional name for variants.
- Group: the primary model or surface, such as
Page,User, orArticle. - Name: the variant inside that group, defaulting to
default.
Article pages can be registered under the Page group with the article name so Page-based features can still find the specialized article resource.
Registering Resources
Section titled “Registering Resources”use App\Filament\Resources\CustomResource;use Capell\Admin\Data\AdminSurfaceContributionData;use Capell\Admin\Facades\CapellAdmin;
public function boot(): void{ CapellAdmin::contributeToAdminSurface( AdminSurfaceContributionData::resource(CustomResource::class, group: 'Custom'), );}For a Page variant:
use App\Filament\Resources\ArticleResource;use Capell\Admin\Data\AdminSurfaceContributionData;use Capell\Admin\Enums\ResourceEnum as AdminResourceEnum;use Capell\Admin\Facades\CapellAdmin;
public function boot(): void{ CapellAdmin::contributeToAdminSurface( AdminSurfaceContributionData::resource( ArticleResource::class, group: AdminResourceEnum::Page->name, name: 'article', ), );}Looking Up Resources
Section titled “Looking Up Resources”Use AdminSurfaceLookup for runtime lookups.
use Capell\Admin\Support\AdminSurfaceLookup;
$resourceClass = AdminSurfaceLookup::resourceIfRegistered('Article');
if ($resourceClass !== null) { $url = $resourceClass::getUrl('edit', ['record' => $articleId]);}For required resources, use AdminSurfaceLookup::resource($group, $name). It throws when the resource is not registered.
Inspecting Contributions
Section titled “Inspecting Contributions”use Capell\Admin\Facades\CapellAdmin;
$resources = CapellAdmin::getAdminSurfaceRegistry()->resources();$pageResources = CapellAdmin::getAdminSurfaceRegistry()->resourcesForGroup('Page');$pages = CapellAdmin::getAdminSurfaceRegistry()->pages();Add-on Package Resources
Section titled “Add-on Package Resources”Add-on packages should contribute admin resources from their service providers once the package is installed.
use Capell\Admin\Data\AdminSurfaceContributionData;use Capell\Admin\Facades\CapellAdmin;use Capell\Blog\Filament\Resources\Articles\ArticleResource;
public function boot(): void{ CapellAdmin::contributeToAdminSurface( AdminSurfaceContributionData::resource(ArticleResource::class, group: 'Article'), );}The Media library gracefully handles missing resources. Owners with no registered resource display as plain text instead of a link.
Package-Owned Widgets
Section titled “Package-Owned Widgets”Admin exposes extension points for package widgets without hard-coding package product behavior. For example, Pages-list SEO totals and per-page SEO audit panels belong to capell-app/seo-suite, not capell-app/admin.
PageResource::getWidgets() exposes PageResourceWidgetExtender so installed packages can add Pages-list widgets. EditPage::afterSave() dispatches the refresh-seo-audit browser event without depending on an SEO package class, so SEO Suite can refresh its edit-page widget when installed.
Keep this boundary when adding package widgets: Admin owns the hook; the package owns the feature.