Twig in Drupal
What does it mean?
- No PHP in templates (cannot)
- Debugging is different
- Introduces some of the more modern template patterns into Drupal
- More reusable and more standardization within templating
No PHP??
- All gone, PHP cannot be used in a twig file
- Twig eventually compiles into PHP, but PHP code cannot be invoked directly
- Twig comes with some filters/functions out of the box
- Extending Twig within Drupal is fairly easy to create reusable code snippets
Setup Twig: Debug and Caching
- Twig is setup out of the box, but not ideally for development
- Need to turn on debugging and autoloading, and turn off twig template caching
Setup
- Copy example.settings.local.php in the sites/ dir and rename to settings.local.php in sites/default/
- Under 'Disable Dynamic Page Cache', uncomment the setting
- In settings.php, uncomment the lines that add settings.local.php if it exists
- In development.services.yml add the following
parameters:
twig.config:
debug: true
auto-reload: true
Debug Info
- Debug gives you info about the template
- Available suggestions, currently used one
- Useful, but also verbose
- If caching isn't disabled, you'll need to clear cache any time a change in a twig template is made
Using Twig: Render Arrays!
- Twig {{ content }} syntax will render Drupal render arrays
<?php print render($content); ?>
{{ content }}
Hiding
- Hiding fields from the bulk content render is also pretty similar
- Implemented with a filter
- Note: printing a field does NOT automatically hide it from the global content array
<?php hide($content['field_name'); ?>
<div class="main"><?php print render($content); ?></div>
<div class="separate"><?php print render($content['field_name']); ?></div>
<div class="main">{{ content|without('field_name') }}</div>
<div class="separate">{{ content.field_name }}</div>
Drill Down
- Dot syntax or bracket syntax to drill down into an array
- If the key contains a special character, like #, you must use brackets
{{ content.field_shorttext }}
{{ content['field_shorttext'] }}
{{ content.field_shorttext.0['#context']['value'] }}
That's It!
- In terms of rendering content, that's generally as much as you do in a twig template
- Any extended functionality comes from functions, filters, and macros that you define elsewhere but can employ within a twig template, control statements, and extends
{% extends %}
- Extending templates is generally one of the biggest standout features of using a templating engine like Twig
- PHP templating does not support the concept of extending a template
- Extending is almost the opposite of including
- Point to where the template inherits from.
How does extending work?
- A template will extend a parent
- This parent template will be used
- Parent templates can 'yeild' content blocks to templates which are extending them
- These blocks can have defaults
- You can also modify variables set in the extended template
- Example!
The Good!
- In Drupal extending will probably most often be used to define a flexible default, ie node.html.twig which more specific templates may extend, ie node--page.html.twig
- Can be great for keeping code dry
- This doesn't mean you should always extend, it's not always appropriate
The Not-So-Good!
- In the rest of the PHP world, the concept of extending templates is often used to determine page layouts
- This only makes sense in a bottom up type of rendering system, ie - a router hits the template to render, and you go up the ladder building the page
- Drupal is a top down system
- Extension will be limited to keeping code DRY and modular as opposed to determining structure
Filters!
- These allow you to directly modify content you are rendering in your template file
- upper, lower, capitalize, escape
- The PHP logic hides in the filter and is implemented in the twig template
- Filters can take parameters
{{ 'I am a string!'|upper }} ... I AM A STRING!
{{ 'Look, ma, no spaces!|squish }} ... Look,ma,nospaces!
{{ 'Still no spaces, amazing!'|remove_char(' ') }} ... Stillnospaces,amazing!
What is the role of filters?
- In Drupal, this can be a bit vague for a few reasons
- Drupal handles a lot of layout and display features via field formatters
- A filter can be used in a custom field formatter for example, or directly in a node template.
- In Twig, filters generally take a string
- In Drupal, you only have a string if you drill down into the render array to find it
- Examples!
Extending Twig
- Twig is easy to extend in Drupal by creating a simple module
- Standard info file
# e3_twig/e3_twig.info.yml
name: E3 Twig Extensions
description: Define some reusable Twig extension
package: Custom
type: module
core: 8.x
Services File
- Defines the new class that will provide the functionality
# e3_twig/e3_twig.services.yml
services:
e3_twig.my_twig_extension:
class: Drupal\e3_twig\TwigExtension\MyTwigExtension
tags:
- { name: twig.extension }
New Class
<?php
namespace Drupal\e3_twig\TwigExtension;
class MyTwigExtension extends \Twig_Extension {
/* Generates a list of all Twig filters that this extension defines. */
public function getFilters() {
return array(
'leet' => new \Twig_Filter_Function(array($this, 'makeLeet')),
'dasherize' => new \Twig_Filter_function(array($this, 'dasherize')),
);
}
/* Gets a unique identifier for this Twig extension. */
public function getName() {
return 'e3_twig.my_twig_extension';
}
/* Makes passed string 1337 */
public static function makeLeet($string) {
$leet_string = str_replace(array('e', 'E', 'a', 'A', 'o', 'O', 'l', 'L', 't', 'T'), array('3', '3', '4', '4', '0', '0', '1', '1', '7', '7'), $string);
return $leet_string;
}
/* Dasherizes passed string */
public static function dasherize($string) {
$string = str_replace(' ', '-', $string);
$string = strtolower($string);
return preg_replace('/[^A-Za-z0-9\-]/', '', $string);
}
}
Custom Functions
- Can be defined in the same module
- Use getFunctions instead of getFilters
- Functions are things like, max, min, random
Macros
- Prebuilt shortcuts for chunks of code given certain passed parameters
- Like, Live Templates in PHP storm
Lots of Opportunity
- For internal collaboration
- To reuse code snippets within a project
- To reuse code snippets across projects
- Create a larger set of available tools for themekit
Drupal and Twig
By Anthony Simone
Drupal and Twig
Using twig in Drupal 8
- 977