If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeWe can now create custom Stimulus controllers with ease. The other half of StimulusBundle is the ability to get more free Stimulus controllers by installing a UX package. Let's add one and see how it works!
Let's start by adding Turbo. At your terminal, say:
composer require symfony/ux-turbo
Here's the juiciest part: just like when we added Stimulus, there's absolutely nothing else you need to do to set this up. Refresh and... it just works! Turbo eliminates the need for full page refreshes. Head over to your Network tools and click on "Fetch/XHR". Let's actually clear this out so we can see everything. Perfect. Then, if we click up here... you can see that this is coming from an AJAX call! Yup, those full page refreshes are gone. So Turbo just works. There's no build system to get in the way, and that's beautiful.
In practice, this works because a new JavaScript file is being loaded called turbo_controller.js
. Filter the network calls to JavaScript... and refresh, because I cleared them. There we go! Our page loads turbo_controller.js
and that imports @hotwired/turbo
, which starts Turbo.
Open up importmap.php
. When we installed the UX Turbo package, its recipe added this new @hotwired/turbo
entry.
... lines 1 - 15 | |
return [ | |
... lines 17 - 29 | |
'@hotwired/turbo' => [ | |
'url' => 'https://cdn.jsdelivr.net/npm/@hotwired/turbo@7.3.0/+esm', | |
], | |
]; |
This is a really common pattern with UX packages: if a UX package depends on a third-party package, its recipe will add that package to your importmap
automatically. The result is that, when that package is referenced - like import '@hotwired/turbo'
- it just works.
The real question is: who's loading turbo_controller.js
, which lives deep inside the symfony/ux-turbo
PHP package?
The answer is: the same trick we learned a moment ago. Search for controllers
and open that file in a new tab. This is the dynamic file that StimulusBundle builds. As it turns out, it looks for packages in our assets/controllers/
directory, which is these two, and it reads the assets/controllers.json
file. When we installed UX Turbo, it added this new section here, which is where we activate different controllers. It activated one called turbo-core
with "enabled":
true and added another deactivated one with "enabled": false
. So when this file is built, it parses the assets/controllers.json
file, finds the controllers that we've enabled, and adds them here.
{ | |
"controllers": { | |
"@symfony/ux-turbo": { | |
"turbo-core": { | |
"enabled": true, | |
"fetch": "eager" | |
}, | |
"mercure-turbo-stream": { | |
"enabled": false, | |
"fetch": "eager" | |
} | |
} | |
}, | |
"entrypoints": [] | |
} |
The final result is that it imports that controller file here and exports it so that the loader.js
file can register it in Stimulus. So any controllers in assets/controllers/
or in this file are registered automatically.
Head back into base.html.twig
. When we installed StimulusBundle, its recipe came bearing gifts - one of which was this ux_controller_link_tags()
. Right now, that does nothing. However, some UX packages come with CSS files. You'll find them under a key called autoimport
, which the recipe will add under the controller. This ux_controller_link_tags()
finds all the CSS files for all the controllers you have activated, and it outputs them. Nothing too fancy.
Next: let's learn one more thing about Stimulus, which just happens to be one of my favorite things: how to make our controllers lazy.
Hey,
It looks like something is not fully configured, or maybe some services are cached. It will be better to double-check a version of StimulusBundle and maybe try to re-install or update it.
Did you get it on the course code?
Cheers!
I've reinstalled symfony/stimulus-bundle, same issue.
I do have webpack encore installed, though -- could there be a conflict? Can both be used simultaneously?
{% block stylesheets %}
{{ encore_entry_link_tags('app') }}
{{ ux_controller_link_tags() }}
{% endblock %}
there could be a version conflict, can you please share what exact version of bundles you have installed (stimulus one and encore)?
cheers!
// composer.json
{
"require": {
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"babdev/pagerfanta-bundle": "^4.0", // v4.2.0
"doctrine/doctrine-bundle": "^2.7", // 2.10.0
"doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.4
"doctrine/orm": "^2.12", // 2.15.2
"knplabs/knp-time-bundle": "^1.18", // v1.20.0
"pagerfanta/doctrine-orm-adapter": "^4.0", // v4.1.0
"pagerfanta/twig": "^4.0", // v4.1.0
"stof/doctrine-extensions-bundle": "^1.7", // v1.7.1
"symfony/asset": "6.3.*", // v6.3.0
"symfony/asset-mapper": "6.3.*", // v6.3.0
"symfony/console": "6.3.*", // v6.3.0
"symfony/dotenv": "6.3.*", // v6.3.0
"symfony/flex": "^2", // v2.3.1
"symfony/framework-bundle": "6.3.*", // v6.3.0
"symfony/http-client": "6.3.*", // v6.3.0
"symfony/monolog-bundle": "^3.0", // v3.8.0
"symfony/proxy-manager-bridge": "6.3.*", // v6.3.0
"symfony/runtime": "6.3.*", // v6.3.0
"symfony/stimulus-bundle": "^2.9", // v2.9.1
"symfony/twig-bundle": "6.3.*", // v6.3.0
"symfony/ux-turbo": "^2.9", // v2.9.1
"symfony/web-link": "6.3.*", // v6.3.0
"symfony/yaml": "6.3.*", // v6.3.0
"twig/extra-bundle": "^2.12|^3.0", // v3.6.1
"twig/twig": "^2.12|^3.0" // v3.6.1
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.4
"symfony/debug-bundle": "6.3.*", // v6.3.0
"symfony/maker-bundle": "^1.41", // v1.49.0
"symfony/stopwatch": "6.3.*", // v6.3.0
"symfony/web-profiler-bundle": "6.3.*", // v6.3.0
"zenstruck/foundry": "^1.21" // v1.33.0
}
}
This is great, I didn't know about the ux_controller_link_tags().
Alas, when I try to use it I get
Unable to load the "Symfony\UX\StimulusBundle\Twig\UxControllersTwigRuntime" runtime
I think all my bundles and recipes are current, any idea where to look to solve this?