Installation
composer require dyg81/modal-bundle
Add to config/bundles.php:
return [
// ...
Dyg81\ModalBundle\Dyg81ModalBundle::class => ['all' => true],
];
Basic Twig Usage
Include the modal script in your base template (e.g., base.html.twig):
{{ modal_script() }}
First Modal Trigger In a controller:
use Dyg81\ModalBundle\Modal\ModalManager;
public function showModal(ModalManager $modalManager)
{
$modalManager->addModal('my-modal-id', [
'title' => 'Hello',
'body' => 'This is a test modal.',
]);
return $this->render('some/template.html.twig');
}
Display in Twig
{{ modal('my-modal-id') }}
// Controller
$modalManager->addModal('alert-modal', [
'type' => 'alert',
'title' => 'Warning',
'body' => 'This action cannot be undone.',
'buttons' => [
['text' => 'OK', 'class' => 'btn-primary', 'onclick' => 'modalClose()'],
],
]);
<!-- Twig: Define a modal with a form -->
{{ modal('form-modal', {
'title': 'Create User',
'body': render(controller('App\\Controller\\UserController::formModalContent'))
}) }}
// Controller: Render form content separately
public function formModalContent()
{
return $this->render('user/_form_modal.html.twig');
}
// Frontend: Trigger modal via JS
fetch('/trigger-modal', {
method: 'POST',
headers: { 'X-Requested-With': 'XMLHttpRequest' },
})
.then(response => response.text())
.then(html => {
modalManager.addModal('dynamic-modal', {
'title': 'Dynamic Content',
'body': html,
});
});
Create a base template (resources/views/modals/base.html.twig):
{% block modal_content %}{% endblock %}
Extend in other templates:
{% extends 'modals/base.html.twig' %}
{% block modal_content %}
{{ include('user/_form.html.twig') }}
{% endblock %}
Embed a Symfony form in a modal:
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
Use modalClose() in the form's onSuccess JS event to close after submission.
Link to a modal route:
<a href="{{ path('app.modal_route') }}" class="modal-link">Open Modal</a>
Add CSS to .modal-link:
.modal-link {
display: inline-block;
cursor: pointer;
}
Override default translations in config/packages/dyg81_modal.yaml:
dyg81_modal:
translations:
ok: 'Confirmar'
cancel: 'Cancelar'
Modal ID Collisions
user-edit-{{ user.id }}) to avoid overwrites.$modalManager->clearModal('temp-modal-id');
JavaScript Conflicts
$() or modal() conflicts.// Override in your JS file
jQuery(document).ready(function($) {
// Your code here
});
Symfony 5.3+ DI Changes
get() calls.->getService() or dependency injection where needed.Twig Auto-escaping
|raw in Twig or sanitize content server-side.Check Modal Existence
if ($modalManager->hasModal('test-modal')) {
// Modal exists
}
Clear All Modals
$modalManager->clearAllModals();
Inspect Rendered HTML Override the modal template to debug:
{% extends 'Dyg81ModalBundle::modal.html.twig' %}
{% block modal_content %}
{{ dump(modal) }} {# Debug modal data #}
{{ parent() }}
{% endblock %}
Console Logs
Enable debug mode in config/packages/dev/dyg81_modal.yaml:
dyg81_modal:
debug: true
Custom Modal Types Extend the base modal template:
{% extends 'Dyg81ModalBundle::modal.html.twig' %}
{% block modal_body %}
<div class="custom-modal-body">
{{ parent() }}
</div>
{% endblock %}
Add CSS/JS Assets
Override the bundle’s assets in config/packages/dyg81_modal.yaml:
dyg81_modal:
assets:
css: ['/bundles/dyg81modal/custom.css']
js: ['/bundles/dyg81modal/custom.js']
Event Listeners
Subscribe to modal events (e.g., modal.show):
// src/EventListener/ModalListener.php
public function onModalShow(ModalEvent $event) {
if ($event->getModal()->getId() === 'special-modal') {
$event->setTitle('Updated Title');
}
}
Register in services.yaml:
services:
App\EventListener\ModalListener:
tags:
- { name: kernel.event_listener, event: dyg81.modal.show, method: onModalShow }
Server-Side Validation Use Symfony’s form validation with modals:
{{ form_errors(form) }} {# Display errors in modal #}
How can I help you explore Laravel packages today?