Need help with Drupal or Grav admin, site building, design, or content? Contact us!
Help Defend Democracy! → Join Battalion today.
Exploring the Symfony universe!
Learn how to make the code for your site's frontend simpler, cleaner, dryer, more logical, and secure with Twig.
Twig is a PHP templating language that outputs variables into the HTML of views in MVC (models, views, controllers) programming. So, it contributes to the structure of a website's frontend.
For your future reference, here's the link to the official TWIG repository on GitHub. I will link to it at the bottom of the article as well.
Let's begin our exploration of TWIG with a brief look back at its history.
On October 7, 2009, Fabien Potencier wrote this article introducing the world to his new creation, Twig. He felt that while PHP was usable as a templating engine, its syntax was "just plain ugly".
He noted that "a template language is something that helps you to write templates that respect this (MVC) separation of concerns. A template language should find a good balance between giving enough features to ease implementing the presentation logic and restricting the advanced features to avoid having the business logic cripple your templates."
Fabien fostered Twig with inspiration from the Django templating language. When he searched for a modern templating language, he found Twig as Armin Ronacher of Jinja fame wrote it. At that point, he asked Armin for permission to hack and open-source Twig. Then, he and his company SensioLabs got to work.
Symfony has bundled support for Twig as its default template engine since version 2. As Symfony grew, so did Twig. And the rest is history.
Before we get into Twig, what exactly are PHP templates? As noted above, they are used to separate the view of your PHP application from its models and objects.
Smashing Mag writes: "The main idea behind the MVC model is that the business logic happens in one place, while the content generation is sent to the user (or view) in another place. Thus, from one set of variables, you can generate many different views. Twig does the same job as the simple example above but in a more sophisticated way. It has many useful features that enable you to develop and maintain your projects more easily and quickly."
To put it more simply, as SymfonyCasts does, Twig or any templating engine is "a tool used to output variables inside HTML."
It is a modern, robust, OOP-based engine.
And according to the official documentation:
"Twig is both designer and developer-friendly by sticking to PHP's principles and adding functionality useful for templating environments.
The key features are:
Many Open-Source projects like Symfony and Drupal use Twig. And it's supported by many more, including Laravel.
The extension .html.twig is used by Twig files. These files consist of static data such as HTML and Twig constructs for dynamic data.
The language uses double curly brace delimiters {{ }} for output and double curly brace percentage delimiters {% %} for logic. In addition, the syntax of {# #} is used for comments. That's it.
SymfonyCasts calls these “{{ }} The "say something" syntax and {% %} The "do something" syntax. I find this an easy way to think of it.
Years ago, Smashing Magazine noted Twig's "advantages are rich features, extensibility, good documentation, security, and speed (it compiles your templates to the native PHP language)." All of this is still true today.
Twig is well supported and has a large user base. Many frameworks and tools integrate it. And Twig helps separate and componentize your code to keep it dry. Plus, it's more secure compared to plain PHP templating. Finally, it makes your code easier to read.
According to Wikipedia:
“The following integrated development environments support Twig:
Eclipse via the Twig plugin
Komodo and Komodo Edit via the Twig highlight/syntax check mode
NetBeans via the Twig syntax plugin (until 7.1, native as of 7.2)
PhpStorm (native as of 2.1)
These text editors support it:
Atom via the PHP-twig for atom
emacs via web-mode.el
Notepad++ via the Notepad++ Twig Highlighter
Sublime Text via the Twig bundle
TextMate via the Twig bundle
vim via the Jinja syntax plugin or the vim-twig plugin
Brackets via Brackets Twig
Visual Studio Code via the Twig extension
GTKSourceView via the Twig language definition
Coda via the Twig syntax mode
Coda 2 via the other Twig syntax mode
SubEthaEdit via the Twig syntax mode”
Since much of the community uses PhpStorm, here's a link to its Twig documentation.
You can test your Twig code on Twigfiddle.com.
A quick note, this is an overview, not a tutorial. So if you are looking for that, here is a short tutorial to get you started in Symfony. And one for using it in Drupal.
As you've probably figured out by now, you build templates with Twig.
Joe Ferguson has an article in an edition of PHP Architect. Here he explains: "template engines provide a mental shift in how you're thinking about your application. We're no longer in the server-side context; we're building what the user will see on their end of the request. This cue is a good reminder that we should not execute any business logic or fetch data from our database here."
He continues: "The goal of using a templating engine is not to make things harder by forcing you to learn a new (templating) language. Instead, the goal is to have a middle ground where dynamic applications meet static HTML elements. They also allow us to limit the functionality of a template, so potentially dangerous functions like eval() or exec() can't be used. My first experience working with templating engines was to have a more natural way to work with HTML in editors without having PHP, HTML, or JavaScript in the same file. In addition, the use of a templating engine allowed the abstraction of our PHP code to be limited to the controller and not tempt us to do more in a template than we should."
A powerful feature of Twig is its template inheritance which removes duplication and promotes maintenance.
As another article from PHP Architect notes: "Usually, we organize our template folders per controller (folder) and action (filename), for example, templates/post/list.html would be used by the list method of a PostController."
Typically, you will create a master layout template (ex. base.twig.html) or several others. And these can inherit from other templates with smaller layouts and dynamic functionality. Headers, footers, menus, buttons, etc are examples. Unique pages may inherit the base (about) or not (a blog or landing page), but any can inherit single-purpose templates.
Regarding organization, @PHParch continues, "This is vital if we want to keep DRY: we should be able to define, for instance, an element once in our templates and refer to it from everywhere else. These shared template resources usually end up in a special folder like partial."
The linked article above's author, Gert Wijnalda, and company, RedAnt "developed Twig Components and the accompanying Twig Components bundle for Symfony, both installable through Composer." The duo certainly makes constructing your user interface easier via the Symfony component tag.
Gert continues: "there needs to be a consistent way to route code results to Twig. Twig Components provide the means to ensure this consistent way of generating frontend HTML."
Speaking of tags.
Twig utilizes tags, filters, and functions, and it also has tests and operators. You can reference the entire list here.
You are familiar with tags from HTML. For example, you've likely used import, include, embed, or cache.
Two of the most useful for building your Twig layouts, according to SymfonyCasts are: "the extends and block tags. When we use extends, it says that this template should be placed inside of a layout. But Twig is a bit dumb: it doesn't know where to put the content from another template. The block tag fixes that. By putting a block body in the layout and a block body around our homepage content, Twig knows exactly where the content should live in the layout."
Extends pulls in your parent template (the one being extended) into a child template. Content that is outside of the blocks defined in your parent template will not be allowed in your child template.
In an article for Electric Citizen, Adam Fuchs explains: "Include also inherits content of a file, but also allows variables from the current template to replace those from the parent template. Include also differs from extends in that template you include is included directly where the call is placed in the child. Think of it this way—extends is like bringing a parent template into a child template and changing some of the parent's content inside the child. Include brings a child template into a parent by inserting the entire child template at a specific point. You could also insert an entire parent into a child and replace variables but not content."
Read that again if you need to. I did. ;)
Continuing SymfonyCast's analogy, like PHP or JavaScript, Twig has functions that can be used to "say something or do something".
If you're using Twig inside something like Symfony or Drupal even more functions are available. Symfony provides many more features via the symfony/twig-bridge Composer package. To see them scroll down on the reference list link above.
Here's a simple function example from the SymfonyCast course, Twig Templating for Friendly Frontend Devs:
<div class="price">
{{ random() }}
{# random(10) returns a number from 0 to 10 #}
{% if random(10) < 5 %}
Really cheap!
{% endif %}
</div>
You can use the dump function can be for debugging.
You can write your own Twig functions as Macros. Mr. Fuchs notes: "Macros can be defined anywhere in your Twig template structure. So one strategy is to define them inside the template you are going to use them in or in the top-level template of that group.
For instance, a macro to build a specific block structure may be defined in block.html.
A better strategy might be to define all of the macros in one file that is not used anywhere on the site."
Again via SymfonyCasts: "Macros can be a huge tool when you're building some reusable functionality. In some ways, using a macro is similar to using the include() function. Both allow you to move markup and logic into a separate place and then use it. The biggest advantage of a macro is that it's very clear what variables you need to pass to it. But like with the include() function, macros can also live in totally different files."
Twig Filters provide particular functionality. Examples include working with currency, time and dates, encoding, and much more.
You can use default filters with your variables and expressions to further control the results. A pipe always precedes twig filters. |
The Twig_Filter allows you to create custom filters.
Both functions and filters can have arguments.
Twig is quite extensible. According to Twig, it “can be extended in many ways; you can add extra tags, filters, tests, operators, global variables, and functions. You can even extend the parser itself with node visitors.” Consult the docs for more information on your unique objectives.
Twig also has internals. They are a bit above my coding experience so I will just quote the documentation.
“Twig is very extensible and you can hack it. Keep in mind that you should probably try to create an extension before hacking the core, as most features and enhancements can be handled with extensions.”
Like Symfony, Twig has recipes. Again, consult the docs for detailed explanations.
As you can see there is much more to Twig that you can explore through the documentation.
However, I prefer to learn by doing, so the SymfonyCast course, Twig Templating for Friendly Frontend Devs, was enlightening.
Their free Harmonious Symfony course has two chapters on Twig:
If you have made it to the end here, you have seen that:
If you haven’t tried Twig it’s worth checking out. If you have, I hope you learned something new.
Thanks for reading the article, and be sure to join our newsletter list at the bottom of this page. Then you will never miss any new original content from Symfony Station or our weekly news communiques.
And if you found this article helpful, please share it via the buttons below!
Learn more
If you registered for SymfonyWorld Online Winter 2022 check out -> Working with Twig in Symfony “Tips and tricks”. https://live.symfony.com/account/replay/video/600
Repository
https://github.com/twigphp/Twig
Sources
http://fabien.potencier.org/templating-engines-in-php.html
https://en.wikipedia.org/wiki/Twig_%28template_engine%29
https://www.phparch.com/article/taming-twig-crafting-high-quality-dry-templates/
https://symfonycasts.com/screencast/twig
https://twig.symfony.com/doc/3.x/
https://twig.symfony.com/doc/3.x/api.html
https://twig.symfony.com/doc/3.x/templates.html
https://www.jetbrains.com/help/phpstorm/symfony-twig.html
https://www.smashingmagazine.com/2011/10/getting-started-with-php-templating/
https://scoutapm.com/blog/3-ways-to-reuse-twig-templates-in-symfony
https://www.digitalnadeem.com/2021/05/02/drupal-twig-tutorial/
https://www.electriccitizen.com/citizen-blog/twig-drupal-8-development-twig-templating-part-1-2
https://www.electriccitizen.com/citizen-blog/twig-drupal-8-development-twig-templating-part-2-2
Happy coding Symfonistas!
Symfony Station covers the essential news in the Symfony, PHP, and Fediverse development communities with a focus on protecting democracy. Please use the button above to make a small donation to help cover our out-of-pocket costs. Our labor is provided free of charge to support the communities we write about.
Subscribe to The Payload, our weekly newsletter exploring the Symfony Universe.