Twig Processing Order & Scope
Tags: twig, frontend, craftcms
Published: 2020-02-14 22:41:20

---
title: Twig Processing Order & Scope
published: true
date: 2016-11-28 15:31:00 UTC
tags: twig,frontend,craftcms
canonical_url: https://nystudio107.com/blog/twig-processing-order-and-scope
---

# Twig Processing Order & Scope

### The Twig tem­plat­ing lan­guage has a lit­tle-known pro­cess­ing order & scope that is impor­tant to understand

Andrew Welch / [nystudio107](https://nystudio107.com)

![Twig Code](https://nystudio107-ems2qegf7x6qiqq.netdna-ssl.com/img/blog/_1200x675_crop_center-center_82_line/112/twig_code.jpg)

Twig is a fan­tas­tic fron­tend tem­plat­ing lan­guage from [Sen­sio Labs](http://twig.sensiolabs.org/) that’s gain­ing wide­spread adop­tion. My first expo­sure to it was in [Craft CMS](https://craftcms.com/), but it’s being used in a num­ber of CMS’s & frame­works such as Sym­fony, Grav, Dru­pal 8, Octo­ber CMS, Bolt, etc. It can even be used in Word­Press via [Tim­ber](https://upstatement.com/timber/). This wide­spread use makes it a valu­able skill to master.

The rea­son Twig is gain­ing wide­spread adop­tion is that it com­bines ease of use with flex­i­bil­i­ty and pow­er. Fron­tend devel­op­ers who are com­fort­able writ­ing HTML and maybe a lit­tle JavaScript can pick up Twig very quickly.

For the most part, Twig is pret­ty straight­for­ward to learn and imple­ment. I’ll assume that you’re famil­iar with Twig; if you’re not, check out the [Twig Book](http://twig.sensiolabs.org/pdf/Twig.pdf) (skip ahead to Chap­ter 3: Twig for Tem­plate Designers).

There are, how­ev­er, two non-obvi­ous aspects of Twig: pro­cess­ing order and scope.

## Twig Pro­cess­ing Order

I cre­at­ed a handy info­graph­ic on Twig Pro­cess­ing Order a bit ago, and will be div­ing in a bit deep­er here.

![Twig Processing Order](https://nystudio107-ems2qegf7x6qiqq.netdna-ssl.com/img/blog/_992x1550_crop_center-center_100_line/twig_processing_order.png)

Here are the code exam­ples used in the above infographic:

```
{{ foo }}
{% set foo = 'ruff' %}
{% include '_include' %}

{% block content %}
{% endblock %}

{% block notoverridden %}
	{{ foo }}
{% endblock %}



{% extends '_layout' %}

{% set foo = 'bar' %}

{% block content %}
	{{ foo }}
{% endblock %}



{% set len = foo |length %}
{% set foo = 'woof' %}
{{ foo }}

```

This is a pret­ty typ­i­cal tem­plate set­up in Twig. We have a <kbd>_layout.twig</kbd> that _includes_ <kbd>_include.twig</kbd>, and a <kbd>page.twig</kbd> that _extends_ our <kbd>_layout.twig</kbd> template.

The inter­est­ing part here is the order in which these things are processed:

1. The code in <kbd>_page.twig</kbd> that is **not** in a <kbd>`{% block %}`</kbd>
2. The code in <kbd>_layout.twig</kbd> that is **not** in a <kbd>`{% block %}`</kbd>
3. The code that is includ­ed in <kbd>_include.twig</kbd>
4. The <kbd>`{% block %}`</kbd> code in <kbd>_page.twig</kbd>
5. The <kbd>`{% block %}`</kbd> code in <kbd>_layout.twig</kbd>

Now, you may say ​“Okay, that’s great, but why does it mat­ter?” Usu­al­ly, it does­n’t. But there are sit­u­a­tions that will leave you scratch­ing your head try­ing to under­stand what’s going on if you don’t under­stand this Twig pro­cess­ing order.

The exam­ple code above would out­put the following:

```

bar
woof
ruff
ruff

```

Is that what you expect­ed? While it may seem arbi­trary, the pro­cess­ing order is actu­al­ly done this way for a very impor­tant rea­son: we need to be able to over­ride things in our tem­plates that extend oth­er templates.

## Twig Scope

Hey, wait a minute… did­n’t we change <kbd>foo</kbd> to <kbd>'woof'</kbd> via <kbd>`{% set foo = 'woof' %}`</kbd> in the <kbd>_include.twig</kbd> tem­plate? Why was that nev­er out­put? Let me intro­duce you to the con­cept of _scope_.

Vari­ables in Twig exist only in the _con­text_ in which they are defined. Sub­sti­tute ​‘tem­plate’ for ​‘con­text’, and you’ll prob­a­bly under­stand it a bit bet­ter. In oth­er words, if we define a vari­able in one of our tem­plates, it exists only there.

For exam­ple, if in our <kbd>_include.twig</kbd> tem­plate we did <kbd>`{% set woof = 'bark' %}`</kbd>, the vari­able <kbd>woof</kbd> will not be avail­able in our <kbd>page.twig</kbd> or our <kbd>_layout.twig</kbd> tem­plates. It’s only avail­able for use in the <kbd>_include.twig</kbd> tem­plate where we defined it.

Aha, but then how are we access­ing the vari­able <kbd>foo</kbd> (defined in our <kbd>page.twig</kbd> tem­plate) from the <kbd>_include.twig</kbd> tem­plate? The answer is that Twig pass­es down a  **copy** of the cur­rent con­text to tem­plates that we include.

Copy is the key word here. While we can access <kbd>foo</kbd> in <kbd>_include.twig</kbd>, any changes we make to it will not be prop­a­gat­ed back up to <kbd>page.twig</kbd> or <kbd>_layout.twig</kbd>. That’s why we nev­er saw <kbd>woof</kbd> get out­put anywhere.

And indeed, when we include tem­plates in Twig, we can add vari­ables to the Twig con­text it will inher­it like this <kbd>`{% include '_include' with { 'someVar': 'someValue' } %}`</kbd>. We can even say we don’t want to include any of the par­ent con­text (only the val­ues we pass in) via <kbd>`{% include '_include' with { 'someVar': 'someValue' } only %}`</kbd>. Check out the [Twig docs](http://twig.sensiolabs.org/doc/tags/include.html) for details.

For­tu­nate­ly, tem­plates that extend oth­er tem­plates share the same con­text, so vari­ables are both acces­si­ble & change­able in this case. 

## Wrap­ping Up

That’s it. Twig pro­cess­ing order and scope may seem a bit eso­teric, but under­stand­ing how your tools work under the hood will save you many hours of frus­tra­tion try­ing to fig­ure out why things are not work­ing as expected.

Hap­py templating!

## Further Reading

_If you want to be notified about new articles, follow [nystudio107](https://twitter.com/nystudio107) on Twitter._

<small>Copyright ©2020 nystudio107. Designed by nystudio107</small>