Introducing Twig Components
Last week I published the Twig Components Drupal module - the latest in a series of projects aiming to combine Twig, Web Components, and PHP. I wanted to write about why I’m doing this work, and why developers should care.
Web Components - a Time and Place
That aside aside, the coolest part of custom elements to me is that they move a lot back to the DOM. The API for custom elements is HTML, you use them the same way you would use any other tag. Asking “Why custom elements” is like asking “Why <input>?”. If a custom element is useful, use it!
In my view, Web Components are a great fit for template-heavy CMSes. Frontend developers are probably already writing HTML templates/CSS/JS, so if anything Web Components are just a way to codify what you already do. This is not a revolutionary technology, but I think it’s something that bridges the very real gap between traditional CMSes and fully-fledged frontend frameworks.
I would also say that, at least out of the box, Web Components are not as ambitious as frontend frameworks, and do not aim to solve the same problems. Web Components don’t come with a solution for routing, state, or context, but what they do solve is componentizing HTML/CSS/JS in something that acts like any other native element. It’s worth nothing that people have built entire web applications with Web Components, but I don’t think that’s the 80% use case.
Discovering Universal Twig
If you’re a Symfony or Drupal 8 developer, you probably have seen or used Twig, a PHP template engine designed to be fast and flexible. I like writing Twig, and from what I can tell most of the Drupal community does as well. Some like it so much that they’ve created massive Atomic Design based themes that already include dozens of re-usable, componentized Twig templates.
I knew going into Web Components that I wanted to use Twig on the backend and the frontend - both for my own preference and to ease PHP developers into this uncharted territory.
So I set out to server-side render Web Components in PHP, and it turned out pretty well. My Composer project, mortenson/twig-components-ssr, now supports nested components, <style> tags in templates, and the <slot> element. At this point, I felt like I could push forward on a Drupal integration.
The end of the funnel
The first thing I added to the module is a new plugin annotation for components, which could be used in a class or a YML file. Using the plugin system was a little tough, but worth it since it gave me discoverability, cacheability, and extensibility. I based a ton of the code and tests on the Layout component and Layout Discovery module from Drupal core, so it may look eerily familiar.
Once plugins were in place, I started working on an event subscriber that responds to every HTML response in Drupal, pre-renders all components, and ensures that only the minimally required libraries are present on the page. You can read the documentation for the renderer for more details.
With a way for modules and themes to provide Twig Components, and assurance that server-side rendering and dynamic library addition works, I released the module on Drupal.org.
At this point, I just need users to create real things with it before I know what direction to take with the module. If anyone is interested in diving in and trying this out, you can jump into the documentation on Drupal.org here.