Skip to content

feat: allow the host app to register its own management page - #200

Merged
ManukMinasyan merged 2 commits into
3.xfrom
feat/configurable-management-page
Aug 12, 2026
Merged

feat: allow the host app to register its own management page#200
ManukMinasyan merged 2 commits into
3.xfrom
feat/configurable-management-page

Conversation

@ManukMinasyan

Copy link
Copy Markdown
Collaborator

Problem

The management config block covers slug, navigation sort/group and cluster. But Filament reads several things off the page class itselfgetSubNavigation(), breadcrumbs, header actions — and config cannot reach any of them.

A consumer that wants the custom fields screen inside its own settings navigation therefore has to subclass CustomFieldsManagementPage and register the subclass on the panel. CustomFieldsPlugin::register() still adds the packaged page unconditionally, and Panel::getPages() de-duplicates by class string only — so the app ends up with two routes to the same screen, one of them unlinked.

The cluster option is not a way out: Page::getRoutePath() applies the cluster slug as a route prefix, so it moves the URL as a side effect of wanting navigation.

Solution

CustomFieldsPlugin::managementPage() — swaps the registered page rather than adding to it, so there is exactly one route either way.

CustomFieldsPlugin::make()
    ->managementPage(\App\Filament\Pages\Settings\CustomFields::class)
class CustomFields extends CustomFieldsManagementPage
{
    public static function getSlug(?Panel $panel = null): string
    {
        return 'settings/custom-fields';
    }

    public function getSubNavigation(): array { /* ... */ }
}

The class must extend CustomFieldsManagementPage (guarded with an InvalidArgumentException), so every packaged behaviour is inherited by default and a consumer overrides only what it needs. Default behaviour is unchanged when the option is not used.

Testing

tests/Feature/ManagementPageOverrideTest.php covers the default, the override, the subclass guard, and that register() puts only the override on the panel. I verified that last one is load-bearing by reverting register() to the hardcoded class — it fails.

  • Package suite: 827 passed, 3 todos
  • Pint and PHPStan clean

Pre-existing on 3.x, not touched here: composer test:type-coverage reports 99.4% (below the 100% gate) and Rector flags tests/Feature/ConsumerScopeHooksTest.php:469. Both reproduce with my changes stashed.

Filament reads sub-navigation, breadcrumbs and header actions off the page
class, none of which the `management` config block can reach. Consumers that
want the custom fields screen inside their own settings navigation had no
option but to subclass and live with the packaged page still registered on the
panel — a second, unlinked route to the same screen.

`CustomFieldsPlugin::managementPage()` swaps the registered page instead of
adding to it, so there is exactly one route either way. The class must extend
`CustomFieldsManagementPage`, so all packaged behaviour is inherited by default.
Copilot AI lite review requested due to automatic review settings August 11, 2026 22:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

is_subclass_of() is false for the class itself, so passing
CustomFieldsManagementPage::class — a legitimate explicit 'use the default' —
threw. is_a(..., allow_string: true) accepts the class and its subclasses.
@ManukMinasyan
ManukMinasyan merged commit 926f37c into 3.x Aug 12, 2026
4 checks passed
@ManukMinasyan
ManukMinasyan deleted the feat/configurable-management-page branch August 12, 2026 18:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants