Weave Code
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 Theme Bundle Laravel Package

bml/form-theme-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require bml/form-theme-bundle
    

    For non-Flex projects, add the bundle to AppKernel.php:

    new Bml\FormThemeBundle\BmlFormThemeBundle(),
    
  2. First Use Case: Define a custom Twig theme for a form type in configureOptions():

    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    
    class MyFormType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder->add('name');
        }
    
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults([
                'theme' => '@App/Form/my_form_theme.html.twig', // Path to your Twig template
            ]);
        }
    }
    
  3. Create the Theme Template: Place my_form_theme.html.twig in templates/App/Form/ (or your preferred path) and extend it:

    {% extends 'form_theme.html.twig' %}
    
    {% block form_row %}
        <div class="custom-form-row">
            {{ form_widget(form) }}
            {% if form.errors|length > 0 %}
                <div class="errors">{{ form_errors(form) }}</div>
            {% endif %}
        </div>
    {% endblock %}
    
  4. Use the Form Type:

    $form = $this->createForm(MyFormType::class, $entity);
    

Implementation Patterns

Workflows

  1. Theme Inheritance: Use Twig’s extends to inherit from Symfony’s default form themes (form_theme.html.twig) or other custom themes. Override blocks like form_row, form_widget, or form_end for granular control.

  2. Dynamic Theme Paths: Pass dynamic theme paths via configureOptions:

    $resolver->setDefaults([
        'theme' => function ($options) {
            return $options['dynamic_theme'] ? '@App/Form/dynamic_theme.html.twig' : null;
        },
    ]);
    
  3. Theme Composition: Combine multiple themes by chaining form_theme calls in Twig:

    {% form_theme form '@App/Form/base_theme.html.twig' %}
    {% form_theme form '@App/Form/override_theme.html.twig' %}
    
  4. Reusable Themes: Create modular themes (e.g., _field.html.twig, _errors.html.twig) and include them in your main theme:

    {% include '@App/Form/_field.html.twig' with {'form': form} %}
    

Integration Tips

  • Symfony UX/Twig: Works seamlessly with Symfony UX components (e.g., Turbo, Stimulus) for dynamic form updates. Example: Use data-turbo-frame in your theme for SPA-like behavior.

  • Form Events: Modify themes dynamically via PRE_SET_DATA or POST_SUBMIT events:

    $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
        $event->getForm()->getConfig()->setTheme('@App/Form/dynamic_theme.html.twig');
    });
    
  • Asset Management: Co-locate CSS/JS with themes (e.g., templates/App/Form/my_theme.css) and reference them in Twig:

    {{ asset('bundles/app/form/my_theme.css') }}
    
  • Testing: Test themes with PHPUnit by mocking the FormView and asserting rendered HTML:

    $view = $form->createView();
    $this->assertStringContainsString('<div class="custom-form-row">', $view->children['name']->vars['full_name']);
    

Gotchas and Tips

Pitfalls

  1. Theme Path Resolution:

    • Issue: Twig autoloader may fail if paths use @Bundle/ syntax but the bundle isn’t registered.
    • Fix: Use absolute paths (e.g., @App/Form/theme.html.twig) or ensure bundles are loaded in AppKernel.php.
  2. Caching:

    • Issue: Twig cache may serve stale themes after changes.
    • Fix: Clear cache (php bin/console cache:clear) or use debug:config-parameters to force reload.
  3. Form Theme Overrides:

    • Issue: Global form_theme in base templates (e.g., base.html.twig) can conflict with per-form themes.
    • Fix: Use {% block form_theme %}{% endblock %} in base templates to allow form-level overrides.
  4. CSRF Token Placement:

    • Issue: Misplaced {{ form_widget(form.vars.csrf_token) }} can break form submission.
    • Tip: Use Symfony’s default form_rest block or place tokens in a hidden field:
      {{ form_widget(form.vars.csrf_token) }}
      
  5. Nested Forms:

    • Issue: Themes for nested forms (e.g., collections) may not inherit parent themes.
    • Fix: Explicitly set themes for child forms or use form_theme in Twig for nested blocks:
      {% form_theme form.child 'app/form/nested_theme.html.twig' %}
      

Debugging

  • Check Rendered Themes: Use {{ dump(form.vars.theme) }} in Twig to inspect active themes.
  • Symfony Profiler: Enable the Web Profiler to debug form rendering in the "Form" tab.
  • Twig Debug: Set TWIG_DEBUG=1 in .env to see template inheritance chains.

Extension Points

  1. Dynamic Theme Selection: Override configureOptions to conditionally set themes:

    $resolver->setDefaults([
        'theme' => function ($options, $form) {
            return $form->getParent() ? '@App/Form/nested_theme.html.twig' : null;
        },
    ]);
    
  2. Theme Registry: Create a service to manage themes centrally:

    # config/services.yaml
    services:
        App\Service\FormThemeRegistry:
            arguments:
                $themes: ['@App/Form/default.html.twig', '@App/Form/admin.html.twig']
    

    Then inject into form types to switch themes programmatically.

  3. Custom Theme Directives: Extend Twig with custom filters for theme logic:

    {% filter custom_theme_filter(form) %}
        {{ form_widget(form) }}
    {% endfilter %}
    
  4. Theme Validation: Validate theme paths in configureOptions:

    $resolver->setDefined('theme');
    $resolver->setAllowedTypes('theme', 'string');
    $resolver->setNormalizer('theme', function ($theme, OptionsResolver $resolver) {
        if (!file_exists($theme)) {
            throw new \InvalidArgumentException("Theme file not found: $theme");
        }
        return $theme;
    });
    
  5. Legacy Support: For Symfony <5.3 (where form_theme was natively added), use this bundle as a drop-in replacement for the PR feature. Test thoroughly for edge cases.

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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle