-
-
Notifications
You must be signed in to change notification settings - Fork 165
Add guide for custom Stimulus controllers #1764
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,91 @@ | ||||||
| --- | ||||||
| title: "Adding Stimulus Controllers" | ||||||
| description: "How to add custom Stimulus controllers for the back end." | ||||||
| aliases: | ||||||
| - /guides/adding-stimulus-controllers/ | ||||||
| --- | ||||||
|
|
||||||
| Since Contao 5 now uses Turbo and Stimulus for the backend, sometimes it might not be enough to register JS assets for the backend as described under [Adding Backend assets][AddingBackendAssets], especially when listening for the `DOMContentLoaded` event. | ||||||
|
|
||||||
| In this case it might be necessary to add a custom Stimulus controller. | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not necessary, but Stimulus makes it way easier to implement what I mentioned above. |
||||||
|
|
||||||
| The following example assumes: | ||||||
| - You're using [Webpack Encore][SymfonyWebpackEncore] for asset management. | ||||||
| - You want to add code for a custom widget. | ||||||
|
|
||||||
| {{% notice info %}} | ||||||
| This guide is meant for bundle development. | ||||||
| {{% /notice %}} | ||||||
|
|
||||||
| ### Adding a custom Stimulus controller | ||||||
|
|
||||||
| ```js | ||||||
| // assets/controllers/my-custom-widget-controller.js | ||||||
| import { Controller } from "@hotwired/stimulus"; | ||||||
|
|
||||||
| export default class MyCustomWidgetController extends Controller { | ||||||
| connect() { | ||||||
| // do your stuff | ||||||
| } | ||||||
|
|
||||||
| disconnect() { | ||||||
| this.#cleanup(); | ||||||
| } | ||||||
|
|
||||||
| beforeCache() { | ||||||
| this.#cleanup(); | ||||||
| } | ||||||
|
|
||||||
| #cleanup() { | ||||||
| // revert the markup before caching and when disconnecting | ||||||
| } | ||||||
|
|
||||||
|
|
||||||
|
Comment on lines
+42
to
+43
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| ### Adding your Stimulus application | ||||||
|
|
||||||
| ```js | ||||||
| // assets/backend.js | ||||||
| import { Application } from "@hotwired/stimulus"; | ||||||
| import MyCustomWidgetController from "./controllers/my-custom-widget-controller"; | ||||||
|
|
||||||
| const application = Application.start(); | ||||||
| application.register("my-vendor-prefix--my-custom-widget", MyCustomWidgetController); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
|
||||||
| // Call the beforeCache() function on all controllers implementing it. This | ||||||
| // allows controllers to tear down things before the page gets put into cache. | ||||||
| // Note that Stimulus' disconnect() function will not fire at this point and | ||||||
| // thus cannot be used for this task. | ||||||
| document.documentElement.addEventListener('turbo:before-cache', (e) => { | ||||||
| for (const controller of application.controllers) { | ||||||
| if ('function' === typeof controller.beforeCache) { | ||||||
| controller.beforeCache(e); | ||||||
| } | ||||||
| } | ||||||
| }); | ||||||
| ``` | ||||||
|
Comment on lines
+57
to
+68
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we really need to include this bit here. I think it would be better to keep it short and simple and just refer to the internals here. Whether you want something to be executed before the page is being put into the cache really depends on the controller. Ideally a simple controller should not need to care. @m-vo wdyt? |
||||||
|
|
||||||
| ### Registering your Stimulus application | ||||||
|
|
||||||
| ```json | ||||||
| // package.json | ||||||
| { | ||||||
| … | ||||||
| "devDependencies": { | ||||||
| "@hotwired/stimulus": "^3.2", | ||||||
| // any other dependencies you need for your controller/application | ||||||
| }, | ||||||
| … | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| Read more about developing Stimulus controllers [here][StimulusControllers]. | ||||||
|
|
||||||
| Regarding `#cleanup()` and `beforeCache()`, also check the notes on idempotency under [Turbo-compatible Stimulus controllers][StimulusBackend] | ||||||
|
|
||||||
| [AddingBackendAssets]: /guides/adding-back-end-assets | ||||||
| [SymfonyWebpackEncore]: https://symfony.com/doc/current/frontend/encore | ||||||
| [StimulusControllers]: https://stimulus.hotwired.dev/handbook/introduction | ||||||
| [StimulusBackend]: /internals/_stimulus-backend | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of Stimulus by the Contao back end is irrelevant here - only the use of Turbo matters. But even that is not completely correct. Even the legacy JavaScript of the Contao back end might add, remove or modify existing DOM nodes, so it is always a good idea to write JavaScript that can handle any kind of DOM manipulation.