## Explorations in re-using Twig templates for the front-end
- Eirik Morland
- Developer at Ny Media
- [eiriksm@github](https://github.com/eiriksm/)
- [eiriksm@drupal.org](https://www.drupal.org/u/eiriksm)
- [@orkj](https://twitter.com/orkj)
- Background: Masters in art criticism
- Beer geek and animated gif enthusiast (gif ratio 36.1%)
The backstory for this talk was this animated gif I posted about 3 years ago. I just checked it out, and it was in January 2015, and the Drupal version in question was Drupal 8, beta 4
## What we will cover
- Part 1: What is the story behind getting where we are now?
- Part 2: What is the current state of how we can do this?
- Part 3: What are some usecases for implementing it?
- Part 4: What are some bad examples of template-sharing code-bases?
- Part 5: Hacks, tips and tricks
These are the things we will go through. But. To get to the bottom of this, I will tell you a magical tale about 2 families. And so to make these bullet points more interesting, and since this is now a tale, lets switch out these bullet points...
## What we will cover
- Chapter 1: Art
- Chapter 2: Magic
- Chapter 3: Heroes
- Chapter 4: Villains
- Chapter 5: Dark sorcery
It will be a tale about art, magic, heroes and villains. Doesnt that sound more exciting. Lets begin!
Once upon a time there were two families living side by side in tiny, tiny village far, far away. This village was called the World wide web. The village may have been not so small, and also not so far away. The two families were called PHP and JavaScript. The families were very different. Different in psychological aspects like temper or maturity. But they were also different in appearance, hipness and weight.
## Chapter 1: Art
But let’s not be so shallow that we only look at appearence, and let’s rather talk about their traditions. They both had traditions, and their own art history.
<marquee>
<blink><?php print $page_title; ?></blink>
</marquee>
The PHP family art were traditionally concerned about having function over form. One early example of traditional PHP art is this classic called “dynamically printing text inside a marquee tag”.
JavaScript was a family that constantly struggled to distinguish themselves from the similarly sounding Java family, and here we can witness one of the most known masterpieces from their early art history called “Making scrolling text inside the status bar”. So in one way, one can say their art history shared a pattern. Scrolling text.
Which is why we can also find reliques of ancient web art where members of both families collaborated on genuine masterpieces like this: “Printing GET parameters inside script tags”.
But time moved fast in the village of the World Wide web. And inside of that history is also something we know as Drupal. And Drupal were a member of the PHP family. And Drupal were now in its eigth generation, where the art was consinting of printing marquee tags with something called Twig.
<marquee>
<blink>{{ page_title }}</blink>
</marquee>
And with this, all things were in place for a thriving art culture in PHP. But the existince of the two families side by side made things not ideal. Many times the base of which the art was built, twig, would be plain wasted because of JavaScripts need to take over their HTML tags.
page.html.twig
<h2>{{ title }}</h2>
<div id="app"></div>
app.js
React.render(
<App />,
document.getElementById('app')
);
Or it would be wasted because of the need for having all HTML tags portrayed by a member of the JavaScript family. Such a waste. Can they not live better together? You know, like the good old masterpiece “Printing GET parameters inside script tags”?
## Chapter 2: Magic
From the JavaScript family a wizard was born. This wizard had magic powers, which could utilize PHPs wonderful new artform in its own environment. This wizard was called twig.js.
### Twig.js
>...a pure JavaScript implementation of the Twig PHP templating language
There is a project called Twig.js, which is esentially
>...a pure JavaScript implementation of the Twig PHP templating language.
Which one would think would mean that a person could now just start using twig in the browser, right? Or maybe not? So let's just dive right into it.
So, The state of things is, we can use twig templates in the browser now. So the hero in this story is then probably twig.js.
## Chapter 3: Heroes
After seeing what the wizard can do, one might think she was a hero to everyone. So let us first look at some of the inhabitants of this village of web that were now cheering for this new hero. Let us look at good use-cases for implementing this.
A place where this approach really can shine is optimistic rendering. For example when posting comments or messages, and you are optimistically rendering the result of that posting, before the server has responded. Here is one example of that, where we can see that the optimistic rendering is using the same node display template as the server, but displays it (at least partially) before it gets rendered on the server.
Another place I think it shines is very simple client side applications, where for example a list is supposed to be updated from time to time. Like "users online". You can render the initial state of the users, and then as it updates, you can use the same template to render the new list of users.
So is this the end of the tale? Are the tribes living together, creating art in beautiful harmony? Well, not really. Things are a bit more complex. Its not only unicorns and raindows. So let's go to the next chapter.
## Chapter 4: Villains
Not everyone in the PHP family was very comfortable with this other family stealing their secret sauce. Their secret sauce being twig. And if this is because of jealousy, greed or just evil is up to the listener to reflect on. We are now going to look at villains in this fairytale. Forces that might bring this wizard down. Let’s look at some bad examples of this strategy.
One really simple example of this about translation. In Drupal twig templates we use a tag called the `{% trans %}` tag, that we use for translation. In vanilla twig.js this simply does not exist. So if we tried to re-use a template that used this tag, it would totally crash in the browser.
But, In a problem solving matter, one can actually extend twig.js to add this trans tag. And with this, also be able to use the trans tag in twig templates in twig.js. But there are other problems.
Let's look at the default node template in bartik.
There are several things here, but let's take a look at the magic variable `{{ content }}`.
Drupal is a flexible system, and to represent this in a template, this variable actually contains all the potential fields a node can have. Images, categories and rich text. To make this possible, Drupal renders all of the contents of content, so to speak.
This is convenient. But very inconvenient if you try to re-use that template for a structure that is similar. [pic of something like that]
## Cost/value
Now the third point I would like to make in this context, is the cost of adding a template language like twig to you client side bundle.
- Twig.js minified is 83K
- React.js + React DOM minified is 46kb
Minified, twigjs clocks in at 83KB [CHECK IT], which is like way more than for example React.
So, say you wanted to include it to do specifically only the users online part, which was examplified earlier. It would be a pretty high cost to include the library only for that. Could there be another way?
## Chapter 5: Dark sorcery
In this JavaScript family, there were also other movements and forces. Forces of a dark type of magic. They said they could perform the magic of the wizard in a quicker and easier way. But it came with a cost. Let’s talk a bit about other ways of achieving similar benefits and the sacrifices one must make. In Drupal 8, we already have a client side library with a template language. No, I am not talking about this language.
I am talking about underscore.js
## underscore.js
Underscore has a template function. It looks something like this:
```js
var compiled = _.template("hello: <%= name %>");
compiled({name: 'moe'});
=> "hello: moe"
```
So what does this have to do with twig? How can this compety with the almight wizard twig.js and her superpowers?
```
var templateSettings = {
interpolate: /\{\{(.+?)\}\}/g
};
```
OK, that was probably a bit abstract, but that enabled us to make templates like this. Does this look familiar?
```
var compiled = _.template("hello: {{ name }}", templateSettings);
compiled({name: 'moe'});
=> "hello: moe"
```
So basically if you have small pieces of your application that needs to be rendered both client side and server side, and those pieces are not nested render arrays, you already have everything you need to be able to achieve this. Of course this a a whole range of limitations. One of them is that the underscore template language does not give you twig for loops, but getting around this would be an excecise for the audience.
## Summary
- The art history of the village of the web is beautiful and constantly evolving
- Some people in this village are heroes, but they might not be everyone’s heroes
- Sometimes there are no wizards that can sprinkle magic dust over your application and give you the bliss of sharing templates
- You can use dark sorcery, but only if you dare
## Resources
- [Twig website](https://twig.symfony.com/)
- [Twig.js website](https://github.com/twigjs/twig.js)
- [Twig.js module for Drupal 8.](https://www.drupal.org/project/twigjs)
- [https://eiriksm.github.io/twig-and-twigjs-talk/ (slides)](https://eiriksm.github.io/twig-and-twigjs-talk/)