tomatophp/tomato-sections-module
TomatoPHP module that adds reusable section management to Laravel and Filament apps. Create, organize, and reuse content sections, control ordering and visibility, and attach them to pages through an intuitive admin interface.
Install the module via Composer and run the standard TomatoPHP module bootstrap:
composer require tomatophp/tomato-sections-module
php artisan vendor:publish --tag=tomato-sections-config
php artisan migrate
Look first at config/tomato-sections.php to understand how section types, renderers, and the Filament resource are wired. The module follows the TomatoPHP convention of registering itself through a service provider and exposing a Filament resource for CRUD management of sections.
The first practical use case is defining a reusable content section (hero, banner, feature grid) that can be attached to pages and rendered from Blade with {!! $section->render() !!} or via a helper. v1.0.3 introduces a register generate command — run php artisan tomato-sections:generate (or the module-prefixed equivalent) to scaffold a new section class with its stub, migration fields, and Filament form schema, rather than hand-rolling boilerplate.
Section-as-class pattern. Each section type is a class (often extending a base Section model or implementing a render contract). Register it in config so the Filament resource can present it as a selectable type. Keep the render logic inside the class and inject data via attributes stored as JSON on the section record.
Generator-driven scaffolding. The new register generate command in v1.0.3 is the intended workflow for adding new section types: generate the stub, edit the form schema and Blade view, then let the module auto-register it. Treat the generator as the source of truth for file layout so newly added sections stay consistent with upstream conventions.
Page composition. Sections are typically attached polymorphically (sectionable) to pages/posts. When rendering a page, eager-load sections ordered by a sort column to avoid N+1, then loop and call render() per section. If your host app uses Filament panels, the module's resource plugs directly into the panel's navigation.
Filament integration. Add the module's resource to your panel provider (->resources([...])) rather than relying on auto-discovery if you split resources across panels. Use Filament's Repeater inside the section form for composite sections (e.g. a feature grid stored as an array of items).
Version pinning. Because this is a young module (v1.0.x), pin to a minor ("^1.0.3") and review each release — the generator command signature and stub templates are the most likely things to shift between patch releases.
array/json) matches how the render method reads them, otherwise you'll get string-not-array errors deep in the Blade view.register generate command produces stubs — check the generated class actually gets registered (config entry or auto-discovery). Regenerated stubs on top of edited files will overwrite your customisations; commit before running it again.orderBy('sort') will appear in insertion order, which breaks when editors reorder in Filament. Always scope the relationship with ordering.php artisan filament:cache-components to rebuild, or optimize:clear) — stale caches are the usual reason a newly generated type doesn't appear in the type dropdown.render() — don't fork the module.app/ rather than editing vendor stubs.How can I help you explore Laravel packages today?