bambamboole/filament-pages

A Filament plugin for managing hierarchical, block-based content pages with a drag-and-drop page tree, SEO integration, and live preview

Fund package maintenance!
:vendor_name

Installs: 5

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 1

pkg:composer/bambamboole/filament-pages

0.1.1 2026-03-03 21:31 UTC

This package is auto-updated.

Last update: 2026-03-03 21:36:16 UTC


README

Latest Version on Packagist GitHub Tests Action Status Total Downloads

A Filament plugin for managing hierarchical, block-based content pages. Features a drag-and-drop page tree, extensible block system (Markdown, Image out of the box), nested pages with automatic slug path computation, multi-locale support, SEO integration, and live preview.

Features

  • Page Tree — Interactive drag-and-drop tree for reordering and nesting pages
  • Block Builder — Flexible content composition with an extensible block system
  • Markdown Block — Rich editor with table of contents, heading permalinks, GFM support, and optional Torchlight syntax highlighting
  • Image Block — Spatie Media Library integration with responsive images and an image editor
  • Custom Blocks & Layouts — Artisan generators for scaffolding your own blocks and layouts
  • Multi-Locale — Locale-scoped page trees with automatic route prefixing and browser language detection
  • SEO — Built-in SEO metadata tab with extensible fields and optional OG image generation via Browsershot
  • Live Preview — Instant page preview powered by Filament Peek
  • Publishing Workflow — Draft, published, and scheduled states with published_at datetime
  • Authorization — Laravel policy support for create, update, delete, and reorder abilities
  • Frontend Routing — Catch-all route registration that resolves pages by slug path and locale
  • Hierarchical Slugs — Automatic slug path computation based on the page tree hierarchy

Screenshots

Page Editor SEO Tab
Page Editor SEO Tab

Installation

composer require bambamboole/filament-pages

Publish and run the migrations:

php artisan vendor:publish --tag="filament-pages-migrations"
php artisan migrate

Optionally publish the config:

php artisan vendor:publish --tag="filament-pages-config"

Register the plugin in your Filament panel provider:

use Bambamboole\FilamentPages\FilamentPagesPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            FilamentPagesPlugin::make(),
        ]);
}

Add the plugin views to your Tailwind CSS content paths:

@source '../../../../vendor/bambamboole/filament-pages/resources/**/*.blade.php';

Configuration

The plugin is configured through the fluent API on FilamentPagesPlugin and the published config file.

FilamentPagesPlugin::make()
    ->seoForm(fn () => [
        TextInput::make('canonical_url'),
    ])
    ->treeItemActions(fn (ManagePages $page) => [
        Action::make('duplicate')->action(fn (array $arguments) => /* ... */),
    ])
    ->previewView('my-custom-preview-view')

Blocks and layouts are configured in the config/filament-pages.php config file:

// config/filament-pages.php
'blocks' => [
    \Bambamboole\FilamentPages\Blocks\MarkdownBlock::class,
    \Bambamboole\FilamentPages\Blocks\ImageBlock::class,
    \App\Blocks\MyCustomBlock::class,
],

'layouts' => [
    \Bambamboole\FilamentPages\Layouts\DefaultLayout::class,
    \App\Layouts\LandingPageLayout::class,
],

Blocks

Register block types in the blocks config array. Each block must extend Bambamboole\FilamentPages\Blocks\PageBlock.

Two blocks ship out of the box:

  • MarkdownBlock — Rich markdown editor with optional table of contents (top/left/right positioning), front matter parsing, and Torchlight syntax highlighting.
  • ImageBlock — Spatie Media Library file upload with responsive images and an image editor.

Layouts

Layouts control how pages render on the frontend. Each layout implements Bambamboole\FilamentPages\Layouts\PageLayout. Register them in the layouts config array.

Multi-Locale

Enable multi-language content by configuring locales in the config file:

// config/filament-pages.php
'routing' => [
    'prefix' => '',
    'locales' => ['en' => 'English', 'de' => 'Deutsch'],
],

When locales are enabled, the page tree filters by locale and frontend routes include a {locale} prefix.

SEO

SEO is always enabled. Every page form includes an SEO tab (powered by ralphjsmit/laravel-filament-seo).

Extend the SEO form with custom fields:

->seoForm(fn () => [
    TextInput::make('canonical_url'),
])

Preview

Live preview is always enabled (powered by pboivin/filament-peek). To use a custom preview view:

->previewView('my-custom-preview-view')

Creating Custom Blocks

Generate a block stub with the Artisan command:

php artisan filament-pages:make-block MyCustomBlock

A custom block extends PageBlock and defines a name, a Filament form schema, and optionally a mutateData() method to transform data before rendering:

use Bambamboole\FilamentPages\Blocks\PageBlock;
use Filament\Forms\Components\Builder\Block;
use Filament\Forms\Components\TextInput;

class CallToActionBlock extends PageBlock
{
    public static function name(): string
    {
        return 'call-to-action';
    }

    public static function make(): Block
    {
        return Block::make(static::name())
            ->label('Call to Action')
            ->schema([
                TextInput::make('heading')->required(),
                TextInput::make('button_text')->required(),
                TextInput::make('button_url')->url()->required(),
            ]);
    }

    public static function viewName(): string
    {
        return 'blocks.call-to-action';
    }
}

Creating Custom Layouts

Generate a layout stub:

php artisan filament-pages:make-layout LandingPageLayout

A layout implements PageLayout and returns a view:

use Bambamboole\FilamentPages\Layouts\PageLayout;

class LandingPageLayout implements PageLayout
{
    public static function name(): string 
    { 
        return 'landing'; 
    }
    
    public static function label(): string { 
        return 'Landing Page';
    }

    public function render(Request $request, Page $page): View
    {
        return view('layouts.landing', ['page' => $page]);
    }
}

Include @filamentPagesStyles in your layout's <head> to load the frontend CSS:

<head>
    @filamentPagesStyles
</head>

Route Registration

Register the frontend page routes in your routes/web.php:

use Bambamboole\FilamentPages\Facades\FilamentPages;

FilamentPages::routes();

This registers catch-all routes that resolve pages by their slug path. You can pass a prefix:

FilamentPages::routes('pages'); // all pages under /pages/*

When locales are configured, routes are automatically prefixed with {locale}.

Frontend Rendering

Pages are rendered through their assigned layout using {!! $page->renderBlocks() !!}.

You can also render blocks programmatically:

$page = Page::where('slug_path', '/about')->first();
echo $page->renderBlocks();

Page Tree

The plugin provides an interactive page tree at /pages in your Filament panel. You can:

  • Drag and drop to reorder and nest pages
  • Create, edit, and delete pages via slide-over modals
  • Publish/unpublish with datetime scheduling
  • Switch between locales
  • Preview pages before publishing

Custom actions can be added to tree items:

FilamentPagesPlugin::make()
    ->treeItemActions(fn (ManagePages $page) => [
        Action::make('duplicate')->action(fn (array $arguments) => /* ... */),
    ])

Authorization

The package supports Laravel policies for access control. Create a policy for your page model to restrict actions:

php artisan make:policy PagePolicy --model=Page

Supported abilities: create, update, delete, reorder.

The package is permissive by default — when no policy is registered, all actions are allowed. Once a policy exists, only explicitly allowed abilities are permitted.

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Credits

License

The MIT License (MIT). Please see License File for more information.