nowo-tech / form-kit-bundle
Symfony bundle to reduce repetitive form field options: convention-based labels/placeholder/help (form_snake.field_snake.*), configurable attr/row_attr/translation_domain, and cascading option merge (global → field type → form → field). Symfony 7.4|8.
Package info
github.com/nowo-tech/FormKitBundle
Type:symfony-bundle
pkg:composer/nowo-tech/form-kit-bundle
Fund package maintenance!
Requires
- php: >=8.2 <8.6
- doctrine/collections: ^2.2
- symfony/config: ^7.4 || ^8.0
- symfony/dependency-injection: ^7.4 || ^8.0
- symfony/form: ^7.4 || ^8.0
- symfony/http-kernel: ^7.4 || ^8.0
- symfony/translation: ^7.4 || ^8.0
- symfony/validator: ^7.4 || ^8.0
- symfony/yaml: ^7.4 || ^8.0
- twig/extra-bundle: ^3.12
- twig/string-extra: ^3.12
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.95.11
- nowo-tech/phpstan-frankenphp: ^1.0
- phpstan/extension-installer: ^1.2
- phpstan/phpstan: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- phpstan/phpstan-symfony: ^2.0
- phpunit/phpunit: ^10.0
- rector/rector: ^2.0
- symfony/framework-bundle: ^7.4 || ^8.0
- vincentlanglet/twig-cs-fixer: ^4.0
Suggests
- a2lix/translation-form-bundle: For the optional "translations" type in FormTypeMap (^3.2 on PHP 8.2/Symfony 7.4, ^4.0 on PHP 8.4+/Symfony 7.4|8)
- friendsofsymfony/ckeditor-bundle: For addCKEditorField() / addCKEditorFieldType() (CKEditor 4 in forms)
- nowo-tech/ckeditor5-editor-bundle: For addCkeditor5Editor() / addCkeditor5EditorField() / addCkeditor5EditorFieldType() (CKEditor 5)
- nowo-tech/icon-selector-bundle: For addIconSelector() / addIconSelectorField() / addIconSelectorFieldType()
- nowo-tech/otp-input-bundle: For addOtp() / addOtpField() / addOtpFieldType()
- nowo-tech/password-strength-bundle: For addPasswordStrength() / addPasswordStrengthField() / addPasswordStrengthFieldType()
- nowo-tech/password-toggle-bundle: For addPasswordToggle() / addPasswordToggleField() / addPasswordToggleFieldType()
- nowo-tech/phone-input-bundle: For addPhone() / addPhoneField() / addPhoneFieldType()
- nowo-tech/select-all-choice-bundle: For addMultiSelectSelectAll() / addMultiSelectSelectAllType() ("Select all" on ChoiceType multiple)
- nowo-tech/slide-to-confirm-bundle: For addSlideToConfirm() / addSlideToConfirmField() / addSlideToConfirmFieldType()
- nowo-tech/tag-input-bundle: For addTagInput() / addTagInputField() / addTagInputFieldType()
- nowo-tech/tiptap-editor-bundle: For addTiptapEditor() / addTiptapEditorField() / addTiptapEditorFieldType()
- symfony/ux-autocomplete: Entity autocomplete fields; use addAutocompleteField() / addAutocompleteFieldType() with your autocomplete FormType FQCN
- symfony/ux-cropperjs: For addCropper() / addCropperField() / addCropperFieldType() (image crop widget)
- symfony/ux-dropzone: For addDropzone() / addDropzoneField() / addDropzoneFieldType() (drag-and-drop file upload)
- symfony/ux-icons: For help_modal.ux_icon (IconRendererInterface) instead of icon_html only
- symfony/ux-live-component: Optional Live Component forms; see the demo /conditional-fields-live page and USAGE conditional-fields section
This package is auto-updated.
Last update: 2026-08-26 10:46:48 UTC
README
⭐ Found this useful? Install from Packagist and give the repo a star on GitHub.
Symfony bundle to reduce repetitive form field options: convention-based translation keys (form_snake.field_snake.label, .placeholder, .help), configurable defaults and multiple profiles via YAML, and cascading option merge (global → field type → form → field).
Minimum requirements: PHP 8.2 and Symfony 7.4. Also compatible with Symfony 8.0 and 8.1 (require PHP 8.4+).
This bundle is FrankenPHP worker mode friendly.
Features
- Usage strategies: Options (
FormOptionsTrait+ FQCN), Kit (FormKitTrait/FormKitAbstractType+ snake_case), Controller (FormKitControllerTrait), Wrapped (AbstractFormKitWrappedType). See Usage — strategies. - Convention-based labels, placeholder and help: Default translation keys are
{form_snake}.{field_snake}.label,.placeholder,.help. Set any tofalsein field options to disable. - Multiple profiles: Define named profiles (e.g.
default,bootstrap) withtranslation_domain,defaults.attr,defaults.row_attr,by_form, and per-field-type options. Choose the active profile per form via#[FormKitConfig('bootstrap')]orsetFormKitConfigName()(named-config technique). - Cascading merge: Options are merged in order: profile defaults → field type →
by_form→ field options. Explicit field options override. - Options strategy helpers:
addText(),addEmail(), … PreferwithBuilder($builder, …)+addTextField()(bound-builder). Or array-build withbuildFormFromArray(). - Choice presets:
addSelect(),addMultiSelect(),addChoiceRadios(),addChoiceCheckboxes(), plusaddMultiSelectSelectAll()when nowo-tech/select-all-choice-bundle is installed (optional Composer suggest). - FQCN helpers:
addAutocompleteField()for Symfony UX Autocomplete types,addCKEditorField()when friendsofsymfony/ckeditor-bundle is installed;addDropzone()/addCropper()when the UX packages are installed. - Nowo-tech widgets (optional):
addOtp(),addPhone(),addPasswordToggle(),addPasswordStrength(),addIconSelector(),addCkeditor5Editor(),addTiptapEditor(),addTagInput(),addSlideToConfirm()— Composer suggest only;LogicExceptionif the package is missing. - Model transformers:
addSwitchType(),addJsonType(),addBoolType(),addMoneyType(),addCsvType()(same helpers on FormKitControllerTrait with*Typesuffix). - Optional types: FormTypeMap includes core Symfony types (including
search) plus optional UX (Dropzone, Cropper), A2lix, and nowo-tech widgets when installed. Extend viatype_map. - Multi-step wizard:
MultiStepFormBuilderfor stepped forms (see the Symfony 8 demo). - Constraint message convention:
constraint_message_conventionplus#[FormKitConfig]/ static field types (StaticAlertType, …). - CSRF-only / GET filters:
CsrfOnlyFormFactory,AbstractGetFilterType,GetFilterFormFactory,SearchQueryType. See docs/CSRF.md. - Form type extensions: InputGroupExtension, RequiredLabelSuffixExtension, HelpModalExtension. See Configuration and Usage.
Installation
composer require nowo-tech/form-kit-bundle
With Flex, the recipe creates config/packages/nowo_form_kit.yaml. Otherwise register the bundle in config/bundles.php and add the config file manually. See docs/INSTALLATION.md.
Quick usage (Options strategy)
- Configure (optional) — edit
config/packages/nowo_form_kit.yaml: setdefault_profile,profiles(each withalias,translation_domain,defaults,field_types), and optionallytype_mapfor custom or UX types. - Register your form as a service and inject FormOptionsMerger:
# config/services.yaml App\Form\UserProfileType: tags: ['form.type'] calls: - setFormOptionsMerger: ['@Nowo\FormKitBundle\Form\FormOptionsMerger']
- Use
FormOptionsTrait(bound-builder or array-build):
use Nowo\FormKitBundle\Form\FormOptionsTrait; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; class UserProfileType extends AbstractType { use FormOptionsTrait; public function buildForm(FormBuilderInterface $builder, array $options): void { $this->withBuilder($builder, function (): void { $this->addTextField('full_name'); $this->addEmailField('email_address'); }); // Or: $this->buildFormFromArray($builder, ['full_name' => TextType::class, 'email_address' => EmailType::class]); } }
- Add translations for keys like
user_profile.full_name.label,user_profile.full_name.placeholder,user_profile.full_name.helpin your translation domain.
Demos
The bundle includes a Symfony 8 demo that runs with FrankenPHP (Caddy + PHP in Docker). Runtime mode is controlled by FRANKENPHP_MODE in the demo .env (default worker; set classic for per-request PHP / easier hot-reload). Change the value and recreate the container (docker compose up -d) — no image rebuild. See docs/DEMO-FRANKENPHP.md. The demo has:
- Locale in the URL — routes are under
/{locale}/…(en,es,fr,de);/redirects to the default locale. - FormType example (contact,
buildFormFromArray), help modal sample (help-modal.js+assets:install; include@NowoFormKitBundle/help_modal/shells.html.twigfor overridable modal shells). - Form built in the controller (
FormKitControllerTrait/FormOptionsMerger::resolve()). - Search, example, Dropzone, Cropper, translations (A2lix), nested, data transformers, choice fields, conditional fields (incl. Live Component), Kit API patterns (snake_case
FormKitAbstractType+ named config), Nowo special fields (OTP, phone, password, icon selector, tags, Tiptap, CKEditor 5, slide-to-confirm — see demo/README.md), CKEditor (FOSCKEditorBundle), UX Autocomplete, multi-step wizard.
Run a demo via Docker/Make from the bundle root; see demo/README.md and docs/CONTRIBUTING.md.
For CSS frameworks, see docs/USAGE.md for ready-to-use configuration examples for Bootstrap 5 and Tailwind CSS.
Documentation
Developer-facing docs and comments (Markdown, PHPDoc, JSDoc) are English only; see Contributing — Language policy.
- Installation
- Configuration
- PSR evaluation (REQ-CS-007)
- Usage
- Flex recipe
- Contributing
- Code of Conduct
- Changelog
- Upgrading
- Release
- GitHub Actions CI requirements
- PHPStan
- Security
- Engram
- Spec-driven development
- GitHub Spec Kit
- Roadmap
Additional documentation
- Demo with FrankenPHP (development and production)
- Help modal (field option + frontend script)
- Overriding bundle templates
Tests and coverage
- Tests: PHPUnit (PHP), Vitest (TypeScript)
- PHP: 99.4%
- TS/JS: 100%
- Python: N/A
License
MIT. See LICENSE.
