- 🇺🇸United States dalemoore
I wonder where this fits now that we have SDC, and Experience Builder is in early development?
Drupal's render & theme system are too complex to use. Let's improve this.
hook_theme()
(with variables
vs render element
), preprocess hooks, theme suggestions and many more related hooks — all tied together using the theme registry#type
(@RenderElement
plugins) vs. #theme
, which are kind of the same thing but not really: when to use which is unclear#pre_render
, #post_render
, #lazy_builder
#render_children
, #theme_wrappers
and friends determining where the render system morphs into the theme system and back againThese have been known problems for years! First there was Form API, then Render API sprouted from that, and all the while there was the theme system, but starting in Drupal 7, the Render API and the theme system got deeply, deeply intertwined. Drupal 8 actually made it slightly better, but not enough.
#type
/@RenderElement
s — but without having to know those details)in other words: bring style guide-driven development to Drupal as a default rather than a labor-intensive, hacked-on after-thought (without the need to duplicate markup and thus keep them in sync).
To address all of those goals, I believe a component library can be the gateway to a solution. It can be, if the following requirements are met:
*.html.twig
(Twig template — which may include some logic to process received variables, just like in Drupal 8)Nothing else.
<extension> (module or theme)
|- components
|- <component name>
|- <component name>.yml
|- <component name>.twig
Concrete example:
core/modules/system
|- components
|- label
|- label.yml
|- label.html.twig
|- label.css
cores/themes/classy
|- components
|- label
|- label.yml
|- label.html.twig
|- ajaxified-label.js
string
/integer
/bool
, B) arrays of primitives such as string[]
, C) other components: component
or components
to slot in other components (perhaps even component:<name>
to only allow certain components ) — this enables 3 big wins:
(Also: having type specifications in Twig templates instead is A) undesirable, B) quite likely impossible, C) quite likely impossible to parse without refactoring Twig, D) would pick up calculated variables.)
*.html.twig
) performs all the necessary processing of the variables received, this ensures we don't depend on preprocess functions. This removes the need for front-end developers to dive into PHP.This part is less precise, but tells a hopefully helpful story of the two most important considerations: how we ended up with the current painful system (recommended reading: http://hackingdistributed.com/2016/04/05/how-software-gets-bloated/) and how we can at the same time start to make it possible to integrate with JS more easily.
And, how, funny enough, those actually need the same fundamental thing: simplicity.
JS: web apps vs web sites
"Apps" are the hot thing in software this decade. But building native apps for every platform is very expensive. So "web apps" are a thing: build once, run anywhere, deploy instantly.
Web apps must be written in JS (or at least compiled to JS), so, consequently, JavaScript is the hot language of this decade. As a result, we've seen enormous investments in JS: Node.js, browser engines' JS interpreters have become incredibly fast, and … JS-based frameworks. From jQuery UI to Angular to Ember to React to …
Everybody wants "an app". And so quite often what would have been a web site a few years ago now is a "web app". And since web apps are written in JS, this means Drupal is less likely to be chosen for those scenarios.
(I personally think the distinction between the two can be made by determining whether the business logic happens in JS on the client or on the server. Only if it's on the client, it is a "web app".)
But that doesn't mean there's no more need for "regular" web sites anymore. It doesn't make sense to build an app just to present hyperlinked information… because for that, we already have an app: the browser. We just need to feed it web sites: documents of structured content, with excellent accessibility & usability, beautiful layout & typography and most importantly: great information architecture.
(And indeed, there is a very, very blurry border between "web sites" and "web apps". I'm just trying to paint a picture of the two extremes, where the world of the web is still finding an equilibrium somewhere in between. And of course, in some cases, it makes sense to have parts on the client side and other parts on the server side.)
Drupal 8 is even better at building web sites than prior versions.
But Drupal is getting pressure to also support "web apps".
So we have a tension between wanting to improve Drupal for what it has traditionally done (improve front-end experience by improving its templates, its markup, removing preprocess functions, etc) and making it possible to build more app-like experiences with Drupal.
But Drupal is not written in JS. Perhaps at some point in the future, there will be tight integration. But we have no idea what that would look like, if it will happen.Getting ready for the future, and facing the past
However, even with the current system, we have long-standing problems. Extremely frustrated reports go back to at least 2011. The theme system and render system are deeply intertwined. It's very confusing. The experience even to build just web sites (not web apps) is far from ideal. Drupal 7 introduced the render system, but let's not forget its origin: Form API. The render system was originally just for forms, but it's since been generalized to be used for all rendering.
- Drupal 6: Form API + theme system
- Drupal 7: Form API + theme system, and both depend on the render system
Drupal 8 has made big steps forward: Twig, removal of most preprocess functions, much cleaner templates,
#theme
is gone in favor of#type
(but not at all completely…), no longer necessary to to sometimes callrender()
in templates …Unfortunately, as soon as the render and theme system interact, it's still painful.
We started working on an experiment at Acquia, where we worked with the Angular & Ember.js teams to do a prototype of what a better commenting experience for Drupal would look like. A reference implementation in Drupal using the AJAX system ("the Drupal way") versus what they would do. They had to reuse our Twig templates. A big problem there was the fact that just about every template has "blobs of HTML":
{{ content }}
, which actually contained the majority of the interesting stuff. And those blobs of HTML are… yes, render arrays!Of course, no JS is ever going to be able to render render arrays, because they're so deeply intertwined with PHP code. And it's impossible to automatically determine which Twig templates are associated with every subtree in a render array.
So this makes it effectively impossible to reuse our Twig templates in JS. Ideally, that would be possible, it'd make Drupal better prepared for the future. It's better to at least have that possibility than not to.
However, even today, and in fact, in years past, this very same problem has been a major frustration for themers: they could only go so far with achieving what they needed to achieve by creating/modifying templates and writing preprocess functions. Very often, they would need to dive deep into render arrays and implement lots of hooks.
Imagine if that weren't the case, and we'd have templates all the way down, rather than enormous blobs of the resulting HTML being defined in render arrays. Imagine if the resulting HTML was wholly based on templates. Templates all the way down. Power to the themers.
And imagine that rather than ill-defined variables, they'd actually have type hints. And validation. And examples. And actually usable documentation rather than incomplete (and duplicated) docblocks. Together, that would allow us to automatically generate a style guide/pattern library.
As a bonus, client-side (re-)rendering becomes possible.
A close-to-comprehensive list of the references I've used to write/build the above.
Lots.
None.
None, only additions.
None, only additions.
Active
Idea
Worse Than Failure. Approximates the unpleasant remark made by Drupal developers when they first encounter a particular (mis)feature.
Enhances developer experience.
Not all content is available!
It's likely this issue predates Contrib.social: some issue and comment data are missing.
I wonder where this fits now that we have SDC, and Experience Builder is in early development?