Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Form Bundle Laravel Package

elasticms/form-bundle

Generate dynamic forms from ElasticMS content configuration. This bundle builds forms out of your content types, keeping field definitions and structure in sync with your ElasticMS content model while rendering them in your Symfony application. Part of the elasticMS mono repository.

View on GitHub
Deep Wiki
Context7

Getting Started

Accept the prerequisite first. This bundle is a thin Symfony layer over elasticMS content-type definitions. Nothing renders until you have a reachable elasticMS instance with at least one content type containing real fields (text, choice, date, file…). If you don't have that, stop here — there is no "hello world" form to demo, and no fixtures in the package.

Where to look, in order:

  1. The official docs: ems-project.github.io/#/dev/form-bundle/index.md. This is the only prose that exists; the README is a stub.
  2. vendor/ after install — specifically the DI extension (DependencyInjection/*Extension.php) and the class that maps an elasticMS field type to a Symfony form type. That mapping is the whole package; read it before writing any code, because it is the documentation.
  3. The elasticMS client/config section of the extension, to see which credentials/host keys you must supply.

Installation reality check. There is no Laravel service provider and no php artisan vendor:publish flow. Two viable paths:

  • Symfony host (recommended): run the bundle in a small Symfony app and expose the rendered form (HTML or JSON schema) to Laravel over HTTP. You keep a clean boundary and avoid fighting the DI container.
  • Laravel host (only if you must): install the bundle's underlying Symfony packages (symfony/form, symfony/validator, symfony/twig-bridge, symfony/translation) and manually assemble the form factory + validator rather than booting the bundle. Verify the published package name and branch in the monorepo metadata first — this repo is marked [READONLY], and releases ship on parallel 6.9.x and 7.x lines that map to different Symfony versions.

First use case to prove out: a single marketing/contact form whose fields live in one elasticMS content type. Fetch the definition, build the form, render it, POST it, validate it, and index the resulting document back into elasticMS. That end-to-end loop exercises every moving part (definitions, mapping, validation, persistence) and takes an afternoon.

Implementation Patterns

Definition → form type. The central pattern is a single reusable form type that takes a content type name (or raw definition) and recursively adds children. Don't generate PHP form classes per form — that defeats the point. Typical flow:

$definition = $this->emsClient->getContentType('contact');   // cache this
$form = $this->forms->create(ContentTypeFormType::class, null, [
    'content_type' => $definition,
]);

Controller shape. GET builds and renders; POST binds request data, calls $form->isValid(), and on success transforms $form->getData() into an elasticMS document payload before indexing. Keep the transform in a dedicated class — you will reuse it for pre-filling edit forms.

Render as a schema, not as Twig. Symfony's FormView is designed for Twig form themes. In a Laravel/Blade or Inertia frontend, the higher-leverage pattern is to serialize the form view (name, type, label, choices, constraints, errors) to JSON in one place and render it with your own Blade/Vue components. One adapter, all forms — and it keeps Symfony's Twig dependency out of your runtime.

Validation dual-track. Map elasticMS constraints to Symfony Constraint objects (the bundle already does part of this). If your controllers are Laravel-native, either run the Symfony Validator on the bound data and mirror the rules as Laravel Rule objects, or — cleaner — validate once with Symfony and translate violations into Laravel's ValidationException so $errors and @error behave normally.

Cache definitions aggressively. Content-type definitions change rarely and API round-trips per page render are the main latency risk. Wrap the client call in Cache::remember() keyed by content type name + a checksum/version, with a short TTL (5–15 min) plus a manual bust on publish.

Multi-tenant / A/B variant pattern. Resolve the content type name from tenant, locale, or experiment bucket (contact_{tenant}_{locale}) at request time and pass it into the form type options. This is the package's strongest use case: no per-tenant PHP branches, and marketing can ship variants without a deploy.

Testing. Fake the client behind an interface returning a fixture JSON definition. Golden-file test the schema serializer — that's where field-mapping regressions surface, not in the form itself.

Gotchas and Tips

  • It is not a Laravel package. No auto-discovery, no facade, no Blade directives. Budget the container-wiring time up front; if that estimate is uncomfortable, use the Symfony sidecar.
  • CSRF clash. Symfony's token manager and Laravel's VerifyCsrfToken middleware will both try to own the token. Pick one — usually disable the Symfony token in the form options and let Laravel's middleware handle it, or exempt the route.
  • Session coupling. Symfony forms with CSRF need session state; Laravel's session driver is not Symfony's. In the sidecar architecture this vanishes — another argument for it.
  • Unmapped field types throw, they don't warn. A new field type added in elasticMS will break form building at runtime. Wrap the mapping in a try/catch that degrades to a generic text field, and log the raw definition.
  • Documents are arrays, not models. elasticMS data is hash-based JSON. There is no Eloquent-equivalent here; write an explicit transformer and don't try to fake a model around it.
  • Translations live in Symfony's translator (messages/validators domains), not Laravel's lang/. Labels from elasticMS are usually pre-translated; constraint messages are not. Normalize both to one source before shipping.
  • Two release lines. 6.9.x and 7.x are maintained in parallel. Pin deliberately and check the Symfony version constraint in composer.json — a mismatch produces confusing DI errors rather than a clean composer conflict.
  • Debugging tip: log the raw content-type JSON alongside the built FormView name tree. Nearly every "field is missing" bug is either a definition cache hit on stale data or a mapping branch that silently skipped the field.
  • Extension points: custom field-type mappers and data transformers registered as services, plus decoration of the client for retries/telemetry. In a Laravel host without the container, plan to subclass or configure these classes directly.
  • Report issues upstream. This repo is [READONLY]; issues and PRs go to ems-project/elasticms. With one star and zero dependents, there is effectively no community Q&A — expect to read source, and price that into the estimate.
  • Failure mode to design for now: elasticMS unreachable = no forms. Cache the last-known-good definition and render a graceful fallback, or the CMS becomes your uptime ceiling.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings