If you’ve ever found yourself working in the Drupal front-end, you will have at some point searched for help on ‘Overriding templates’. It’s a legacy pattern that Drupal just can’t shake. With Drupal 8 we saw some big front-end improvements. Twig was inherited as a templating engine which was supposed to mean working with a more decoupled approach between the back end and front end… but, it’s not that decoupled…
Opinionated Markup Control
There is an old infamous post about Drupal ‘divitis’, illustrating just how wild Drupal’s core markup can get. I’m amazed at how this old post on drupal was ended by a member of the community stating ‘Welcome to Drupal’ and pointing them to the Fences module. This is a bit odd. Not only because the core markup delivered is way over the top, but that the solution to this problem is for the community to offer modules that strip down the markup. It’s pretty backwards. Given this ‘divitus’ issue is so old, it’s not worth dwelling on too much, but what is worth noting is the place it comes from and why it was up to the community to solve it by offering modules to strip back markup rather than trying to fix it.
It was largely caused by the lack of Front-end developers on the core team, so the solution for D7 was to provide everything that was needed for flexibility, a kind of catch-all solution. However, the markup was just far too crowded with divs and class soup. Divs are one thing, but too many useless classes is another, it can drive all developers round the bend. The one thing you can be sure of is that front-end developers need control over class names.
To me, development is about creating what you need, not removing what you don’t need. Surely it’s easier to just write your own code rather than write hundreds of overrides or write a completely new theme? The problem with writing a new theme is that, at least in Drupal 7, it’s a huge task. Because there are so many elements to be styled… so many things from core that you take for granted as being styled aren’t when you create your custom theme. This ends up being a bit of a nightmare in QA. Sure you can use a ‘base theme’ but how do you know what’s done and what isn’t? Don’t believe me? Just visit /node on any drupal site and you’ll more than likely see something unstyled or looking not quite right.
So has this been fixed in Drupal 8?
Using Twig has moved Drupal on a lot. There is more control over markup through the use of a template engine. But there are still areas that are opinionated, cluttered and actually encourage code repetition
Easier templating with Wagtail
Drupal front-end is largely done by overriding core templates. This breaks the DRY development concept in a rather large way. Overriding templates means you are creating new code, for existing code. Drupal works with a template naming convention, so if you want to clean up your markup by writing your own template or more often overriding core ones you have to use a certain name. Our field example above would be something like field — node — field-text-example.html.twig. This has annoyed me more times than I care to remember.
Really this templating problem can be summarised as ‘doing only what you need to do’. With Wagtail it’s clear, you work bottom up because nothing is offered out of the box. With Drupal it’s a bit like navigating a minefield, what do I override? Should I override deeper? What name do I use to override template X? Should I use default classes and write my SASS for that? What if there are core updates that break my front end? It goes to support a difference between Front End Development and Drupal Front End Development and makes it a lot harder for a new front-end developer to get involved. Should front-end developers need to understand the intricacies of template naming conventions? What if they wanted their own naming convention? What if they want a different CSS selector pattern? All of these ‘what if’s’ can become annoying tasks in Drupal, because straight of the bat you end up changing, amending and repeating code rather than explicitly creating a something (see KISS).
Really a true templating system should work with simple, defined includes:
<body>… include header.html
… include whatever_i_want.html
… include content.html
… include footer.html</body>
Then we can do further includes in those templates if we want to. This gives us the power to create something simple, rather than endlessly trying to simplify. And this is what Wagtail does because you start from ultimate simplicity- nothing. It uses the Django templating system and has support for Jinja, which isn’t too different from Twig. But, due to the naming conventions, hundreds of template overrides and preprocess functionality, true front-end developers can pick up Wagtail FE work even if they’ve never used it before. They can explicitly see in the code what’s going on, they don’t have to write preprocess functions to override templates or worry about configuration changes to displays from production. And as a bonus, you don’t have PHP code in your templates.
Drupal 8 Field markup
As a more detailed comparison, let’s look at what a simple field looks like by default. Here is a simple plain text field with a label:
<div class="field field--name-field-pain-text field--type-string field--label-above">
<div class="field__label">Pain text</div>
<div class="field__item">Abbas nobis persto typicus virtus. Lucidus occuro venio.</div>
Want to add your own class? Or override it to strip it down? Sure, just read this, this and you might want to check this. What you will more than likely end up doing is making your own theme, inherit a base theme and override the field template being offered to result in lots of code repetition.
Drupal likes to provide a sort of ‘out of the box’ readiness, and in fairness, it does it very well but that box is massive. Here we have a field, with a label, and the core theme is working well. But I can count on one hand the number of sites I’ve seen use this default core theme. In other words, no one uses this, but end up having to override it. So it stays, in the codebase as a dependency for your theme. 😥
Wagtail Field Markup
Wagtail isn’t opinionated, it doesn’t provide templates or classes you aren’t going to use because there is no default out of the box front end. You have to build it, and in doing so you can be explicit. So your markup can be whatever you desire. It can simply be:
<p>Pain text label</p>
<p>Abbas nobis persto typicus virtus. Lucidus occuro venio.</p>
This to me is pure flexibility. Because it’s up to you. You might suggest that going into the template markup to change a field label is more hassle than changing it through the Drupal UI, but that change will have to be captured with a Drupal config export… then import on production, where you will have to pay attention to other configuration changes.
Drupal Displays and Templates vs Just Templates
Drupal offers a means of configuring layout through the admin UI through the use of displays, whereas Wagtail doesn’t provide anything.
The display system in Drupal is a sort of link between the back end and front end. It’s actually a really powerful part of Drupal when used well, but it does feel like your doing the same thing in 2 places. Configure a display, then tweak the template for it, or just disable the displays and let the template take control. The latter is pretty confusing for anyone to be introduced to, configuration like moving fields around in displays that aren’t going to even be used is a bit odd for both administrators and developers but it’s what seems to work best. The downside of Drupal displays is with the introduction of configuration management, it can cause knock-on effects. Changes to displays have to exported into config (yaml) files and imported to production, but you have to take into account changes to the configuration and pretty soon a Front End developer is doing something they don’t really want to do, fixing merge conflicts for config changes (a huge black hole of time for many projects)
I don’t really see this as decoupled, you have to make quite a lot of modifications to decouple the front and back. But it goes to a more important point that the C is not being focused on in CMS. Drupal has always been sort of mixture of a content management framework and a content managment system. There’s a really good breakdown of those types of comparrisons between Django and Drupal in David Ray and Tim Scales blog post. Users writing content should be concerned with and focused on the content, not how it looks, and front-end developers should be doing front-end, not config conflicts. Django separates these better which gives a much simpler publishing experience and also a much more pleasent developer experience.
Wagtail is actually decoupled.
While the display system is powerful on Drupal, I think for customised and usually large sites it can quickly become more trouble than it’s worth because how something looks is managed in multiple places.
There isn’t a display system in Wagtail linking the back-end to the front. Backend developers are responsible for providing the data and front-end developers are responsible for the markup and styling. There’s no magical way Wagtail solves this problem, nothing amazingly clever, it just doesn’t offer this admin display configuration from the start. I’ll admit, at first I found this a bit weird because wouldn’t it mean I have to write thousands of my own templates? It’s not that scary leaving the concept of displays behind, it’s actually really nice and you have a lot more control over the front end. Sure you have to make templates but you aren’t overriding things and exporting configuration for it, which makes it a lot faster to work with.
Wagtail gives me the flexibility and freedom to set up the front end in a way that suits me and my team — Helen Chapman Front End team leader
Repeating code, overriding code, and struggling with esoteric template conventions just aren’t fun to work with. Front-end developers like to be accurate, and they like to create the very best solutions.
As a framework, being opinionated about Front End is dangerous because front-end is evolving all the time and lately much quicker than the back end. After a few weeks of initial release, developers will have to resort to overriding the FE provided by core for more up to date support and better solutions. It will become more complex even before they write their first template override and code will be repeated all over the place. Keep it simple and start from as close to nothing as you can get.