How to Embed Asynchronous Content with hinclude.js
How to Embed Asynchronous Content with hinclude.js
Embedding controllers in templates is one of the ways to reuse contents across multiple templates. To further improve performance you can use the hinclude.js JavaScript library to embed controllers asynchronously.
First, include the hinclude.js library in your page linking to it from the template or adding it to your application JavaScript using Webpack Encore.
As the embedded content comes from another page (or controller for that matter), Symfony uses a version of the standard render()
function to configure hinclude
tags in templates:
{{ render_hinclude(controller('...')) }}
{{ render_hinclude(url('...')) }}
Note
When using the controller()
function, you must also configure the fragments path option.
When JavaScript is disabled or it takes a long time to load you can display a default content rendering some template:
YAML
# config/packages/framework.yaml
framework:
# ...
fragments:
hinclude_default_template: hinclude.html.twig
XML
<!-- config/packages/framework.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services
https://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
<!-- ... -->
<framework:config>
<framework:fragments hinclude-default-template="hinclude.html.twig"/>
</framework:config>
</container>
PHP
// config/packages/framework.php
$container->loadFromExtension('framework', [
// ...
'fragments' => [
'hinclude_default_template' => 'hinclude.html.twig',
],
]);
New in version 4.3: The framework.fragments.hinclude_default_template
option was introduced in Symfony 4.3. In previous Symfony versions it was called framework.templating.hinclude_default_template
.
You can define default templates per render()
function (which will override any global default template that is defined):
{{ render_hinclude(controller('...'), {
default: 'default/content.html.twig'
}) }}
Or you can also specify a string to display as the default content:
{{ render_hinclude(controller('...'), {default: 'Loading...'}) }}
Use the attributes
option to define the value of hinclude.js options:
{# by default, cross-site requests don't use credentials such as cookies, authorization
headers or TLS client certificates; set this option to 'true' to use them #}
{{ render_hinclude(controller('...'), {attributes: {'data-with-credentials': 'true'}}) }}
{# by default, the JavaScript code included in the loaded contents is not run;
set this option to 'true' to run that JavaScript code #}
{{ render_hinclude(controller('...'), {attributes: {evaljs: 'true'}}) }}
This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.