tomatophp/tomato-forms-module
A Laravel/PHP module that brings customizable form building and management to the TomatoPHP ecosystem, letting you create, organize, and render dynamic forms within your admin panel.
Install the module into an existing TomatoPHP/Filament application:
composer require tomatophp/tomato-forms-module
php artisan vendor:publish --tag=tomato-forms-config
php artisan vendor:publish --tag=tomato-forms-migrations
php artisan migrate
First places to look:
config/tomato-forms.php — toggles for routes, middleware, upload disk, and which Filament panel should expose the resources.src/Models/ — Form and FormEntry/submission models define the schema you will query against.database/migrations/ — the canonical shape of the forms and fields tables; read these before writing any custom query.src/Filament/Resources/ — the admin UI (Form resource and field repeater) that gives you the builder experience for free.The first real-world use case is: build a form in the admin panel, embed it on a public or authenticated page, capture submissions, and browse/export entries from the Filament resource. Do that end-to-end before customising anything — it validates your panel registration, storage disk, and migration state in one pass.
Builder-first, code-second. Define forms through the Filament resource rather than hand-seeding rows. Reserve programmatic creation for reproducible environments (seeders, tests), and if you do it, populate the field schema through the model's own API rather than mass-assigning raw JSON.
Embedding forms. Expose a Livewire/Filament component or a Blade include wired to the form's slug/ID. Keep the embed route behind configurable middleware so the same module serves both a marketing contact form (public) and an internal intake form (auth + policy).
Submission handling. Treat submissions as domain events: listen for the module's entry-created event (or observe the entry model) and dispatch your own jobs for notifications, CRM sync, or file post-processing. This keeps you out of the vendor's controller and survives upgrades.
Validation ownership. Put per-field rules on the field definition at build time, and layer application-specific rules in a form request or a policy-backed component. Never rely solely on client-side rules from the builder.
Multi-panel and multi-tenant setups. Register the resources conditionally per panel in your PanelProvider, and scope entries by tenant in a global scope on the entry model if you run tenancy. This is the single most common integration point where the module needs adapting.
Export and reporting. Wrap the entry model in your own query/export layer (FromQuery, CSV, or a Filament action) instead of extending vendor resources — you get stable column naming and can add computed fields.
"^1.0") and read composer.json constraints before assuming Laravel/Filament compatibility on older apps.vendor:publish reports no matching tag, run php artisan vendor:publish interactively and inspect src/Providers/ for the actual tag names — module packages frequently rename tags between minor releases.config/tomato-forms.php, run php artisan config:clear. Stale cached config is the usual cause of "route not found" and "disk not found" reports.storage:link for public-facing forms; the default disk rarely matches production S3 setups.How can I help you explore Laravel packages today?