02 - December - 2016

The wonders of Twig theming

Post by Paul J

Part of the plan for rebuilding the Ixis site in Drupal 8 was for us to write up some of our thoughts at the end. Writing about the theme layer is hard, because it’s all completely new. There’s a million things I want to talk about, some of the Drupal related, some of them just about frontend tools in general, so I’m going to try and squeeze as much as I can in here.

Bootstrap is awesome

The frontend theme is built on Bootstrap, which allowed us to get the site up and running quickly, and iterate on feedback from the rest of Ixis and the design agency. We only started building the theme 6 days before the site went live!

Using a fairly heavy framework like Bootstrap often raises concerns about performance, but considering that all of the CSS on one of our page loads is ~30kb, it was worth the trade off for the speed of development and iteration. At some point we’ll go through Bootstrap and remove the parts we aren’t using, but right now we’re still iterating and improving things.

Libsass is awesome

We’ve been using Sass for a while at Ixis, it’s amazing for writing clear CSS that can actually be maintained after a few years of iterative development work. Up until now we’ve relied on Compass to compile that for us, but this time we took a look at Gulp and libsass with node-sass.

Damn is it fast. We’re compiling bootstrap-sass as part of our theme, which used to take Compass ages every time we changed a variable. Libsass builds the whole thing in about a second. On top of compiling the CSS, we’re using Gulp on the Ixis site to automatically add vendor prefixes (no more reliance on compass for browser compatibility), provide image mappings (which lets Sass access information about the images, like dimensions) and optimise the file size of those images.

Twig is awesome

I <3 Twig. After so many years of wrangling the Drupal PHPTemplate engine into usable markup, it is so refreshing that everything is templated. No more overriding theme functions just to add an extra class to a div. You don’t even need to use PHP at all to do it.

<article{{ attributes.addClass(‘an-extra-class') }}>

Dealing with render arrays in a template? Just print them! Doesn’t matter what’s in them. Let Twig sort it out. You’ll never again see “Array” printed to the screen because you forgot to pass something through render().

I know a huge amount of effort went into making Drupal 8 more accessible to frontend folks, and it really does seem to have paid off! The only downside is that I still have to go back to the Drupal 7 way of PHP everywhere occasionally to support older sites.

Libraries are awesome

The new libraries.yml file makes it a lot easier to define libraries, which are collections of Javascript and CSS, along with their dependencies, so you can just load things when you need them. No gallery on this page? Drupal won’t load that javascript, and if the gallery was the only reason you needed jQuery then it won’t load that either if no gallery is being rendered on the page. A contrib module that adds a library can now be boiled down to just an info.yml and libraries.yml filebe 2 yaml files in the theme.

Contrib for libraries is in a bit of a weird state in Drupal 8 at the moment. If you’ve used Drupal 7 then you’ve probably used the Libraries API module, it’s there to allow other contrib modules to share third party libraries. It looks like the plan for Drupal 8 is to eventually have a centralised repository of third-party libraries, but currently it doesn’t seem like a lot of contrib is using it, instead just relying on the library being in /libraries in the Drupal root.

Paragraphs are awesome

We went with paragraphs in order to allow content editors a bit of control of the layout of the pages. I won’t waffle too much about how we set up paragraphs because we’ve already talked about that, but from a frontend point of view, each paragraph type has it’s own twig template, and we can load separate libraries just for that one paragraph, so we were able to make each paragraph into it’s own self contained component. Did I mention I love the new Twig stuff in Drupal 8?

Caching is awesome, but you should probably learn how it works

The new caching layer is amazing, it just seems to work magically behind the scenes. It can be quite easy to be caught out by it though, if you don’t understand what’s happening behind the curtain, especially if you’re used to Drupal 7’s way of caching each page.

Here’s an example from building the Ixis site: The logo on our site links to the front page. It’s a fairly common thing to do. If you’re already on the frontpage though, that’s a redundant link, there’s no reason for it to be there and it can confuse things for those using screen readers.

So we added a simple check: If we’re on the front page, just show the logo, otherwise wrap the logo in a link to the front page. Without caching, this works fine. With caching, Drupal caches that block the first time it’s rendered, then uses it everywhere, because we haven’t told Drupal that this block can differ based on path.

In the end, we added a new cache context to the ‘site branding’ block, so Drupal knows it can differ based on the url. We’re currently relying on just the ‘url.path’ context, but in 8.3 there’s a new url.path.is_front context we’ll be using.

Debugging is easy.

Debugging Twig is easy peasy; In your sites/default/services.yml file (copy the one from default.services.yml if it doesn’t exist), then change the debug value to ‘true’.

parameters:

 twig.config:

   debug: true 

Then you get handy comments like this in the page source:

<div class="region region-branding">
 <!-- THEME DEBUG -->
 <!-- THEME HOOK: 'block' -->
 <!-- FILE NAME SUGGESTIONS:
    * block--magicks-sitebranding.html.twig
    x block--system-branding-block.html.twig
    * block--system.html.twig
    * block.html.twig
 -->
 <!-- BEGIN OUTPUT from 'themes/custom/magicks/templates/block/block--system-branding-block.html.twig' -->
 <span class="logo navbar-btn">
   <img width="120" height="44" src="//ixis.co.uk/themes/custom/magicks/logo.svg" alt="Home">
 </span>
 <!-- END OUTPUT from 'themes/custom/magicks/templates/block/block--system-branding-block.html.twig' -->
</div>

You can quickly dump a variable with the dump function like {{ dump(a_variable) }}, which just uses PHP’s var_dump() behind the scenes, but if you want to poke at array they you’ll probably want to use the kint module from devel, which gives you a much nicer output with {{ kint(content) }}. Word of warning, the little + will expand everything, and if it’s a big tree it’ll just crash your browser.

Example of kint output

Frontend developer experience in Drupal 8 is a huge improvement over what was in Drupal 7, and thanks to the new release cycle, it’s continuing to improve even after Drupal 8 has launched. Really looking forward to seeing what new features we’ll get in the future, and I’ll be keeping an eye on the ‘core ideas’ issue queue.

Profile picture for user Paul J

Paul J

Frontend Developer at Ixis. Making Drupal sites easier to use, more interactive and prettier looking.

Add new comment

Share this article

Our thoughts

Let's work together

Get in touch and find out how we can empower your organisation.
Back to top