Installation Add the bundle to your Symfony project via Composer:
composer require ecentria/twig-js-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Ecentria\JMSTwigJsBundle\EcentriaJMSTwigJsBundle::class => ['all' => true],
];
Basic Configuration
Configure the bundle in config/packages/ecentria_jms_twig_js.yaml:
ecentria_jms_twig_js:
enabled: true
twig_js_path: '%kernel.project_dir%/vendor/ecentria/twig-js-bundle/Resources/public/js/twig.js'
First Use Case: Rendering Twig Templates Client-Side
Include the Twig.js script in your base template (e.g., templates/base.html.twig):
{% block javascripts %}
{{ parent() }}
{{ twig_js_script() }}
{% endblock %}
Use Twig.js to render a template dynamically in JavaScript:
Twig.render('{{ path('app_template', { id: 1 }) }}', { data: { name: 'John' } }, function(html) {
document.getElementById('dynamic-content').innerHTML = html;
});
Template Routing
Define a route for your Twig template (e.g., app_template):
# config/routes.yaml
app_template:
path: /template/{id}
defaults: { _controller: 'App\Controller\TemplateController::render' }
Controller:
// src/Controller/TemplateController.php
public function render($id) {
return $this->render('template/partial.html.twig', ['id' => $id]);
}
Client-Side Integration Use Twig.js to fetch and render templates dynamically:
// Example: Load and render a template with data
Twig.render('{{ path('app_template', { id: user.id }) }}', {
user: { name: 'Alice', role: 'Admin' }
}, function(html) {
document.querySelector('.user-profile').innerHTML = html;
});
Partial Templates
Create reusable partials (e.g., templates/partials/_card.html.twig) and render them via Twig.js:
{# templates/partials/_card.html.twig #}
<div class="card">
<h3>{{ data.title }}</h3>
<p>{{ data.content }}</p>
</div>
JavaScript:
Twig.render('{{ path('app_partial', { name: '_card' }) }}', {
data: { title: 'Hello', content: 'World' }
}, function(html) {
document.body.innerHTML += html;
});
{{ asset('bundles/ecentria/twigjs/twig.js') }}
# config/packages/dev/ecentria_jms_twig_js.yaml
ecentria_jms_twig_js:
enabled: true
# config/packages/prod/ecentria_jms_twig_js.yaml
ecentria_jms_twig_js:
enabled: false
ecentria_jms_twig_js:
twig_js_path: '%kernel.project_dir%/public/js/custom-twig.js'
CORS Issues If rendering templates from external domains, ensure CORS headers are configured on the server:
// src/EventListener/CorsListener.php
public function onKernelRequest(GetResponseEvent $event) {
$request = $event->getRequest();
if ($request->isXmlHttpRequest()) {
$response = $event->getResponse();
$response->headers->set('Access-Control-Allow-Origin', '*');
}
}
Template Cache Invalidation Twig.js caches templates client-side. Force a reload by appending a cache-buster:
Twig.render('{{ path('app_template') }}?v=' + Math.random(), data, callback);
Data Sanitization
Twig.js executes templates client-side, so ensure data passed to Twig.render() is sanitized to avoid XSS:
// Sanitize data before passing to Twig.render()
const sanitizedData = Object.fromEntries(
Object.entries(data).map(([key, value]) => [key, String(value).replace(/</g, '<')])
);
Twig.render(templateUrl, sanitizedData, callback);
Twig in the console tab.{{ path('app_template') }} returns a valid URL).cache: false in Twig.js options for debugging:
Twig.render(templateUrl, data, callback, { cache: false });
Custom Filters/Functions Extend Twig.js by adding custom filters/functions in your template:
{# templates/base.html.twig #}
{% block twig_js_extensions %}
Twig.extendFunction('customFilter', function(text) {
return text.toUpperCase();
});
{% endblock %}
Usage in JavaScript:
Twig.render(templateUrl, { text: 'hello' }, function(html) {
console.log(html); // Outputs "HELLO" if customFilter is applied
});
Override Twig.js Globally Replace the default Twig.js instance with a custom build:
// Override Twig globally (e.g., in a global JS file)
window.Twig = {
render: function(url, data, callback) {
// Custom logic here
fetch(url, { method: 'POST', body: JSON.stringify(data) })
.then(response => response.text())
.then(html => callback(html));
}
};
Symfony Event Listeners Hook into Symfony events to modify Twig.js behavior:
// src/EventListener/TwigJsListener.php
public function onKernelRequest(GetResponseEvent $event) {
$request = $event->getRequest();
if ($request->attributes->get('_route') === 'app_template') {
$request->attributes->set('twig_js_data', ['extra' => 'value']);
}
}
Access data in Twig:
{{ dump(app.request.attributes.get('twig_js_data')) }}
How can I help you explore Laravel packages today?