statikbe / laravel-filament-flexible-content-block-pages
A simple content page management system with a flexible content block builder based on the Filament flexible content blocks package.
Fund package maintenance!
Statik.be
Requires
- php: ^8.2
- artesaos/seotools: ^1.3
- filament/spatie-laravel-tags-plugin: ^3.2
- guava/filament-icon-picker: ^2.0
- illuminate/contracts: ^11.0||^12.0
- mcamara/laravel-localization: ^2.3
- solution-forest/filament-tree: ^2.1
- spatie/laravel-missing-page-redirector: ^2.11
- spatie/laravel-package-tools: ^1.16
- spatie/laravel-sitemap: ^7.3
- statikbe/laravel-filament-flexible-content-blocks: dev-main
Requires (Dev)
- larastan/larastan: ^2.9||^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.1.1
- orchestra/testbench: ^10.0.0
- pestphp/pest: ^3.0
- pestphp/pest-plugin-arch: ^3.0
- pestphp/pest-plugin-laravel: ^3.0
- phpstan/extension-installer: ^1.3||^2.0
- phpstan/phpstan-deprecation-rules: ^1.1||^2.0
- phpstan/phpstan-phpunit: ^1.3||^2.0
This package is auto-updated.
Last update: 2025-08-08 14:23:11 UTC
README
A complete CMS solution for Laravel applications built on Filament Flexible Content Blocks. This package extends the flexible content block system into a full page management solution with routing, SEO, menus, and multilingual support.
Designed for developers who need a content management system that integrates seamlessly with existing Laravel applications while providing editors with an intuitive interface for managing pages and content.
Key Features
- Flexible page management - Create pages with hero images, flexible content blocks, SEO fields, and publication controls
- Hierarchical menu builder - Configurable depth with drag-and-drop interface for creating navigation menus
- Multilingual support - Full localization with automatic route generation for multiple languages
- SEO tools - Automatic sitemap generation, meta tag management, and URL redirect handling
- Ready-to-use admin interface - Pre-configured Filament panel with all resources and management tools
- Developer-friendly - Extendable models, customizable templates, and comprehensive configuration options
- Content organization - Tag system, hierarchical page structure, and settings management
Additional Features
- Website routing with customizable URL patterns
- Blade view components and CSS themes
- Media library integration via Spatie packages
- Automatic 301 redirects when page URLs change
- Multiple sitemap generation methods (manual, crawling, hybrid)
- Configurable content block types and layouts
This package combines several Laravel packages into a cohesive CMS solution, making it opinionated but comprehensive for typical content management needs.
Installation
You can install the package via composer:
composer require statikbe/laravel-filament-flexible-content-block-pages
Publish the config file with:
php artisan vendor:publish --tag="filament-flexible-content-block-pages-config"
If you want to alter the names of the database tables, do so in the config file, before running the migrations.
You can publish and run the migrations with:
php artisan vendor:publish --tag="filament-flexible-content-block-pages-migrations" php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="medialibrary-migrations" php artisan migrate
Configure the Filament tailwind styling of the frontend by adding these view paths to content
array of tailwind.config.js
:
content: [ ... './vendor/solution-forest/filament-tree/resources/**/*.blade.php', './vendor/statikbe/laravel-filament-flexible-content-block-pages/**/*.blade.php', './vendor/statikbe/laravel-filament-flexible-content-blocks/**/*.blade.php', './config/filament-flexible-content-blocks.php', ]
In the tailwind config of your filament back-end, add the following lines to the content
array:
content: [ ... './config/filament-flexible-content-blocks.php', ]
You can now seed the home page and default settings by running:
php artisan flexible-content-block-pages:seed
Further configure the third-party packages that are used. Check the installation documentation of these packages:
Laravel Localization:
Make sure the middlewares are properly setup if you want to use localised routes.
Laravel Tags:
Publish the config and change the tag model to the package model:
[ 'tag_model' => \Statikbe\FilamentFlexibleContentBlockPages\Models\Tag::class, ]
Check the configuration documentation for more explanations on how to tweak the package.
Optionally, you can publish the views using
php artisan vendor:publish --tag="filament-flexible-content-block-pages-views"
Setup in your project
Translations
If you want translated content and routes, go through the following steps:
- Configure the supported locales in the Filament Flexible Content Blocks configuration
- Configure the
route_helper
infilament-flexible-content-block-pages.php
Routes
Register the routes in your route file, probably web.php
:
\Statikbe\FilamentFlexibleContentBlockPages\Facades\FilamentFlexibleContentBlockPages::routes();
Filament panel
The package contains a pre-configured panel. You can register the panel in the app.php
configuration file.
'providers' => [ // ... \Statikbe\FilamentFlexibleContentBlockPages\FlexibleContentBlockPagesPanel::class, // ... ],
If you want you can build your own panel from the provided resources.
Schedule
We suggest to add media library maintenance tasks to your schedule in routes/console.php
:
Schedule::command('media-library:clean') ->weeklyOn(1, '11:00'); Schedule::command('media-library:regenerate --only-missing') ->dailyAt('4:20');
Menu builder
The package includes a powerful hierarchical menu builder with a drag-and-drop interface for creating navigation menus. Menus support multiple types of links and can be easily styled with custom templates.
Features
- Hierarchical structure - With configurable max depth per menu
- Multiple link types - Internal routes, external URLs, and linkable models (Pages or your own project model)
- Drag & drop management - Intuitive tree interface for reordering and nesting items
- Multiple menu styles - Default, horizontal, vertical, and dropdown templates included
- Translation support - Multilingual menu labels with locale-aware URLs
- Conditional visibility - Show/hide menu items without deleting them
- Icon support - Optional icons for menu items (basic implementation currently)
- Dynamic labels - Use model titles or custom labels for linked content
Adding linkable models
To make your models available in the menu builder, add them to the configuration:
// config/filament-flexible-content-block-pages.php 'menu' => [ 'linkable_models' => [ \App\Models\Page::class, \App\Models\Product::class, \App\Models\Category::class, ], ],
Your models should implement the [HasMenuLabel](src/Models/Contracts/HasMenuLabel.php)
contract and the HasTitleMenuLabelTrait trait:
use Statikbe\FilamentFlexibleContentBlockPages\Models\Contracts\HasMenuLabel; use Statikbe\FilamentFlexibleContentBlockPages\Models\Concerns\HasMenuItemTrait; class Product extends Model implements HasMenuLabel { use HasMenuItemTrait; public function getMenuLabel(?string $locale = null): string { return $this->getTranslation('name', $locale ?? app()->getLocale()); } }
If you are using the Flexible Content Blocks title trait in your model, you can implement HasMenuLabel
easily with HasTitleMenuLabelTrait
.
Using the 'default' menu style
The package includes a default
built-in menu style which is developed in a generic way so that you can tweak its styling by passing some attributes without having to publish the corresponding blade templates.
Example usage to have a horizontal menu using tailwind:
<x-flexible-pages-menu code="HEADER" style="default" ulClass="flex flex-row justify-start items-center gap-x-4" itemLinkClass="text-black hover:text-primary hover:underline" currentItemLinkClass="text-grey hover:no-underline" />
See the file ../tailwind/components/menu/default.blade.php
for all possible attributes.
Customizing additional menu styles
If needed, you can easily add your own menu styles in addition to the default
style:
- Add new styles to config:
// config/filament-flexible-content-block-pages.php 'menu' => [ 'styles' => [ 'default', 'mega', // Your custom style ], ],
Tip: Add translations if you want UX-friendly style dropdowns.
- Create the template files:
# Main menu template resources/views/vendor/filament-flexible-content-block-pages/tailwind/components/menu/mega.blade.php # Menu item template resources/views/vendor/filament-flexible-content-block-pages/tailwind/components/menu/mega-item.blade.php
- Use in your templates:
<x-flexible-pages-menu code="HEADER" style="mega" />
The style can also be configured in the database model, then you can skip the style
attribute.
See the menu seeding documentation for programmatic menu creation.
Redirects
The package includes automatic redirect management: when the slug of a page changes, a redirect from the old page to the new page is added. These redirects are stored in the database and are managable with the Filament resource, so you can add your own redirects.
Additionally, we integrated spatie/laravel-missing-page-redirector, so you can easily configure other redirects in the spatie packages config.
Configuration
- Prepend/append the RedirectsMissingPages.php middleware to your global middleware stack:
// bootstrap/app.php ->withMiddleware(function (Middleware $middleware) { $middleware->append([ \Statikbe\FilamentFlexibleContentBlockPages\Http\Middleware\RedirectsMissingPages::class, ]); })
- Optional: If you want to hardcode a set of redirects, you can do this in the config file of the spatie package. Publish this package:
php artisan vendor:publish --provider="Spatie\MissingPageRedirector\MissingPageRedirectorServiceProvider"
Sitemap Generator
The package includes an automatic sitemap generator that creates XML sitemaps for your website with support for multilingual sites and various content types.
Features
- Multiple generation methods - Manual, crawling, or hybrid approach
- Multilingual support - Automatic hreflang tags for alternate language versions
- Smart priority calculation - Homepage gets priority 1.0, parent pages 0.8, child pages 0.6
- Dynamic change frequency - Based on last modification date (weekly, monthly, yearly)
- Flexible content inclusion - Pages, routes, linkable models, and custom URLs
- URL exclusion patterns - Skip specific URLs or patterns from the sitemap
- SEO optimization - Includes last modification dates and proper XML structure
Configuration
Enable and configure the sitemap generator in your config file:
// config/filament-flexible-content-block-pages.php 'sitemap' => [ 'enabled' => true, 'generator_service' => \Statikbe\FilamentFlexibleContentBlockPages\Services\SitemapGeneratorService::class, 'method' => SitemapGeneratorMethod::MANUAL, // MANUAL, CRAWL, or HYBRID 'include_pages' => true, 'include_link_routes' => true, 'include_linkable_models' => true, 'exclude_patterns' => [ '/admin/*', '/api/*', ], 'custom_urls' => [ 'https://example.com/special-page', ], ],
Generation Methods
Manual (SitemapGeneratorMethod::MANUAL
):
- Generates sitemap based on database content (pages, routes, models)
- Faster and more predictable
- Best for most use cases
Crawl (SitemapGeneratorMethod::CRAWL
):
- Crawls your website to discover URLs
- May find URLs not in your database
- Slower but comprehensive
Hybrid (SitemapGeneratorMethod::HYBRID
):
- Combines both approaches
- Crawls first, then adds manual entries
- Most comprehensive but slowest
Usage
Generate the sitemap manually:
php artisan flexible-content-block-pages:generate-sitemap
The sitemap will be saved to public/sitemap.xml
and can be accessed at https://yoursite.com/sitemap.xml
.
Automatic Generation
You can schedule automatic sitemap generation in your routes/console.php
:
$schedule->command('flexible-content-block-pages:generate-sitemap') ->daily() ->at('03:00');
Linkable Models
To include your own models in the sitemap, ensure they implement the Linkable
contract and have a getViewUrl()
method.
You will most likely already have added those models to the menu configuration's linkable_models
array or
call-to-actions models then they will automatically be included in the sitemap.
If you do not want your model in menus or call-to-actions, you can extend the SitemapGeneratorService.
Extending the SitemapGeneratorService
For full customization power, you can create your own sitemap generator service by extending the base class:
<?php namespace App\Services; use Statikbe\FilamentFlexibleContentBlockPages\Services\SitemapGeneratorService; class CustomSitemapGeneratorService extends SitemapGeneratorService { protected function addCustomUrls(): void { parent::addCustomUrls(); // Add your custom logic $this->addToSitemap( url: 'https://example.com/dynamic-page', lastModifiedAt: now(), priority: 0.7, frequency: 'weekly' ); } protected function getLinkableModels(): array { $models = parent::getLinkableModels(); // Add additional models not in menu/CTA config $models[] = \App\Models\BlogPost::class; $models[] = \App\Models\Event::class; return $models; } protected function calculatePriority($page): float { // Custom priority logic if ($page->is_featured) { return 0.9; } return parent::calculatePriority($page); } }
Then update your configuration to use your custom service:
// config/filament-flexible-content-block-pages.php 'sitemap' => [ 'generator_service' => \App\Services\CustomSitemapGeneratorService::class, // ... other config ],
You can override any protected method to customize the sitemap generation behavior, including priority calculation, change frequency, URL filtering, or adding entirely new content types.
Configuration
TODO
TODO's
check:
- do install docs work
- Seppe: tailwind config complete? do we need to add flexible content blocks styling?
- Seppe: menu components ok?
menu:
- caching tree model + observer to clear cache
- Menu titels menu items
- Ben: add menu to default page template
- test global search and improve table search and ordering
page:
- Kristof: make table searchable, columns orderable, test global search
- make table searchable, columns orderable, test global search
- laravel scout
release:
- policies:
- note: undeletable pages
- undeletable page toggle only for permission holder
- redirect controller
- tag controller
- documentation
- Kristof: screenshots + banner + packagist + slack + filament plugin store
future:
- A simple asset manager (include or not?)
- Re-usable content blocks
- Contact form
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.