• Like
  • Save
Twig: Friendly Curly Braces Invade Your Templates!
Upcoming SlideShare
Loading in...5

Twig: Friendly Curly Braces Invade Your Templates!



Video: http://youtu.be/Jikkiqt-nBo ...

Video: http://youtu.be/Jikkiqt-nBo

Twig! Yep, it's that fancy magic that's supposed to make theming in Drupal 8 as much fun as eating beef brisket at Rudy's Country Store in Austin (apologies to my veggie friends!). And in fact, Twig was *born* for this: a language that was created with one job in mind: making writing templates awesome and powerful. Oh, and to make you love using it.

In this talk, we'll learn about Twig from the ground-up: syntax, filters, inheritance and other tricks you can learn now to be ready for Drupal 8. We'll also look at how Twig looks inside Drupal, and how it compares to what you're used to in Drupal 7.

By the end, you'll know everything to start getting your Drupal 8 theme on and be shouting its praises from the hills! Ok, maybe not that last part (but I do love how excited Drupalers get), but you'll definitely have a new friend in your world: Twig.



Total Views
Views on SlideShare
Embed Views



0 Embeds 0

No embeds



Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-NonCommercial LicenseCC Attribution-NonCommercial License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

    Twig: Friendly Curly Braces Invade Your Templates! Twig: Friendly Curly Braces Invade Your Templates! Presentation Transcript

    • Being dangerous with Twig
    • A guide to using Twig – the fast, secure and extensible PHP templating engine – to create clean template code, leverage powerful filters, make your designers write you love letters, write template functions that Don't clog up your global PHP namespace, take advantage of true template inheritance, hang out with Django programmers and be able to talk template syntax, enjoy true and non-invasive output escaping, have more time for your family, control whitespace, add global variables to all templates, stop lying when you try to tell yourself that <?php echo looks better than a simple {{, use the fancy for-else control, Rock some macros – little reusable code functions, do awesome stuff like “{% if i is divisibleby 2 %}”, mediate in the simplicity of your templates and drink more green tea, sandbox your template and whitelist capabilities – allowing Twig to be used in a CMS, take advantage of the fact that all templates compile to PHP classes that can extend a base class of your choosing, impress your friends by changing the print tag from {{ var }} to [all-your-base] var [are-belong-to-us], confuse the guy next to you by changing “is” and “is not” to mean the opposite things and convince him that he's misunderstood how logical expressions are used in programming languages all along, create a custom tag that takes the body of its block and tweets it, write templates the expresses presentation and not program logic. Being dangerous with Twig
    • KnpUniversity.com github.com/weaverryan • Lead for the Symfony documentation ! • KnpLabs US - Symfony consulting, training, 
 Kumbaya ! • Writer for KnpUniversity.com screencasts Buenos Dias!
    • Birthday Wishes!
    • Happy Birthday Dad!
    • Happy Birthday Anne-Sophie!
    • Happy Birthday Rafael Nadal
    • Happy Birthday Anderson Cooper
    • Why Twig? Act 1
    • @weaverryan because template engines are awesome
    • @weaverryan $engine = new RyansFantasyTemplatingEngine();
 $tpl = $engine->loadTemplate('drupalcon.php');
 $tpl->render([‘place' => ‘Austin!’]); <!-- drupalcon.php -->
 <h1><?php echo $place ?></h1>
 <?php echo call_some_great_helper('woot!') ?>

    • Template Engines • A template engine allows you to render a presentation (HTML, XML, etc) via a template in a controlled environment ! • It should allow special functionality that makes creating templates easier (helpers, template inheritance, etc) @weaverryan
    • @weaverryan a template engine is a tool
    • @weaverryan why not just render PHP templates?
    • PHP templating woes • rendering template files is a hack: an include statement with output-buffering control ! • no or faked template inheritance ! • no isolation: PHP templates suck in any global variables or functions available @weaverryan
    • @weaverryan we want the brevity of templates ! with the isolation of object-oriented programming
    • @weaverryan so give me some Twiggy pudding Twig is: » fast » flexible » concise » secure » fully-featured » Extensible » designer-friendly Twig offers: » true inheritance » real output escaping » tons of filters » custom tags » great documentation » global variables » the “for-else” control
    • @weaverryan Twig is concise ! and each template compiles to an actual PHP object
    • @weaverryan Seeing is believing https://www.flickr.com/photos/visitfinland/5203910918
    • @weaverryan because template engines are awesome
    • @weaverryan because template engines are awesome
    • @weaverryan because template engines are awesome class __TwigTemplate_617db133b9dd01ce28b55447b extends Twig_Template
 // line 3
 public function block_body($context, array $blocks = array())
 // line 4
 echo " ";
 foreach ($context['_seq'] as $context["_key"] => $context["blog"]) {
 // line 5
 echo " <h2>";
 echo $this->getAttribute($context["blog"]);
 echo "</h2>
    • @weaverryan https://www.flickr.com/photos/melolou/517629486 a moment of templating zen
    • @weaverryan “The template system is meant to express presentation, not program logic.” - Django Documentation
    • @weaverryan Twig can easily be used anywhere
    • @weaverryan require __DIR__.'/vendor/autoload.php';
 $loader = new Twig_Loader_Filesystem(array(__DIR__.'/templates'));
 $twig = new Twig_Environment($loader);
 echo $twig->render('hello.twig', array(
 'name' => 'DrupalCon!'
 {# templates/hello.twig #} 
 {% extends 'layout.twig' %}
 {% block body %}
 Hello {{ name }}!
 {% endblock %}

    • Act 2 Twig’s Simple Life
    • @weaverryan Twig's three tags Twig parses just three tags: ! » comment tag ! » print tag ! » block tag
    • a. do nothing (comment tags) {# comment #} » totally ignored when rendered @weaverryan
    • b. say something (print tags) {{ 'print me!' }} » simply prints the given expression » equivalent to <?php echo » If you're ultimately printing something, use this tag @weaverryan
    • @weaverryan c. do something (block tags) {% set foo = 'inside a block tag' %} » used mostly for control-flow statements like if, for, include and block » can have beginning and end tags » if you're *doing* something and not *printing* something, use this tag
    • @weaverryan Twig’s three tags ! » do nothing: {# comment tag #} » say something {{ ‘print tag’ }} » do something {% block tag %} It’s just that simple!
    • Act 3 Everything is an expression
    • @weaverryan expressions Twig guts » like PHP, most everything inside a tag 
 is an expression ! ! ! ! ! » expressions are the most interesting and 
 flexible part of Twig
    • @weaverryan Expressions Block names Block-specific tokens
    • @weaverryan An expression can consist of many different things https://www.flickr.com/photos/swambo/7617988518
    • @weaverryan strings, numbers and variables » like any language, strings, numbers and variables are commonplace
    • @weaverryan arrays and hashes » arrays use [], hashes use {}
    • @weaverryan operators » just like PHP operators, but extensible
    • @weaverryan filters » filters modify the value that precedes it and 
 are always preceded by a pipe (|) » filters may or may not take arguments
    • @weaverryan functions » returns a value based on an arbitrary input
    • @weaverryan » strings, numbers and variables » arrays and hashes » operators » filters » functions allow Twig to express Twig’s-self Hey! It’s simple like PHP, but flexible
    • Act 4 Twig on the battlefield
    • @weaverryan » a template that displays a list of “widgets” in odd-even rows
 » render info about each widget
 » create basic, clean pagination the test…
    • @weaverryan
    • @weaverryan http://1.bp.blogspot.com/_D_Z-D2tzi14/TBpOnhVqyAI/AAAAAAAADFU/8tfM4E_Z4pU/s1600/responsibility12(alternate).png
    • @weaverryan
    • @weaverryan » the “truncate” filter isn't part of Twig, but is available via a library of extensions
 » Everything in Twig is loaded via an Extension (even the core stuff)
 » Extensions are easy to use and create – we’ll prove it later ! » https://github.com/fabpot/Twig-extensions your presenter is lying to you…
    • @weaverryan http://1.bp.blogspot.com/_D_Z-D2tzi14/TBpOnhVqyAI/AAAAAAAADFU/8tfM4E_Z4pU/s1600/responsibility12(alternate).png
    • @weaverryan
    • @weaverryan https://www.flickr.com/photos/circasassy/7192588208 Flex some filters
    • @weaverryan
    • @weaverryan convenience, readability
    • @weaverryan
    • @weaverryan pagination?
    • @weaverryan
    • @weaverryan » but.... the “radius” function doesn't actually exist in Twig. the audacity: your speaker just lied again But since it's pretty handy, let's create it!
    • Act 5 Twig extensions!
    • @weaverryan » filters » functions » operators » tests (e.g. divisibleby) » custom tags Twig extensions everything in Twig is loaded by an “Extension” class: Extensions are easy!
    • @weaverryan
    • @weaverryan Yes, there is a missing piece of “hooking this up”
    • @weaverryan It’s a small amount of code, involving services
    • @weaverryan Come to my talk tomorrow ;) ! MASTER THE NEW CORE OF DRUPAL 8 NOW: WITH SYMFONY AND SILEX ! 10:45 Room: G - Trellon | 4th floor
    • Act 6 Theming D7 versus D8
    • @weaverryan Good News!
    • @weaverryan The Changes are Underwhelming!
    • @weaverryan From D7 themes to D8 themes » Other than the Twig syntax, things feel very familiar ! » page.tpl.php -> page.html.twig » node.tpl.php -> node.html.twig » THEME.info -> THEME.info.yml ! » THEME_field__taxonomy_term_reference() -> field--taxonomy-term-reference.html.twig
    • @weaverryan <div id="node-<?php print $node->nid; ?>" clear <?php print render($title_prefix); ?>
 <div class="content clearfix"<?php print $con <?php
 print render($content);
 <?php $links = render($content['links']);
 if ($links):
 <div class="link-wrapper">
 <?php print $links; ?>
 <?php endif; ?>
 D7: node.tpl.php
    • @weaverryan <article id="node-{{ node.id }}” role=“article" {{ attributes|without(‘id', 'role') }}>
 <header>{{ title_prefix }}</header> 
 <div class="content clearfix"{{ content_attri {{ content|without('links') }}
 {% if content.links %}
 <footer class="link-wrapper">
 {{ content.links }}
 {% endif %}
 D8: node.html.twig
    • @weaverryan Function overrides
    • @weaverryan D7: template.php function bartik_field__taxonomy_term_reference($ $output = '';
 // Render the label, if it's not hidden.
 if (!$variables['label_hidden']) {
 $output .= '<h3 class="field-label">' . $var }
 // Render the items.
 $output .= ($variables['element']['#label_disp class="links inline">' : '<ul class="links">';
 foreach ($variables['items'] as $delta => $ite $output .= '<li class="taxonomy-term-referen $variables['item_attributes'][$delta] . '>' . dr }
 $output .= '</ul>';

    • @weaverryan D8: field--taxonomy-term-reference.html.twig <div class="{{ attributes.class }} clearfix” {{ attributes|without('class') }}> 
 <h3{{ label_attributes }}>{{ label }}: </h3> 
 <ul class="links">
 {% for delta, item in items %}
 <li class="taxonomy-term-reference- {{ delta }}"{{ item_attributes[delta] }} >{{ item }}</li>
 {% endfor %}

    • Act 7 after-dinner mint Mmmmm…..
    • @weaverryan Debugging
    • @weaverryan /**
 * settings.php
 * Twig debugging:
 * When debugging is enabled:
 * - The markup is surrounded by HTML comments
 * - The dump() function can be used * - Templates are automatically recompiled
 $settings['twig_debug'] = TRUE;
    • @weaverryan … inline suggestions about the template to override …
    • @weaverryan … dump *all* variables you have access to …
    • @weaverryan <article id="node-{{ node.id }}" ...>
 {{ dump() }}
 {# ... #}
    • @weaverryan … or just dump the names of the variables …
    • @weaverryan <article ...>
 {{ dump(_context|keys) }}
    • @weaverryan Inheritance
    • @weaverryan {% block header %}
 {{ title_prefix }}
 {% if not page %}
 <h2{{ title_attributes }}>
 <a href="{{ node_url }}">{{ label }}</a>
 {% endif %}
 {{ title_suffix }}
 {% if display_submitted %}
 <div class="meta submitted">
 {{ user_picture }}
 {{ submitted }}
 {% endif %}
 {% endblock %} node.html.twig
    • @weaverryan {% extends "core/themes/bartik/templates/node.html.twig" %}
 {% block header %}
 <h1 class="header">{{ label }}</h1>
 {% endblock %}
    • @weaverryan {% extends "core/themes/bartik/templates/node.html.twig" %}
 {% block header %}
 <div class="article">
 {{ parent() }}
 {% endblock %}
    • @weaverryan dot.notation
    • @weaverryan Am I working with an array? <?php print render($page['header']); ?> <div id="node-<?php print $node->nid; ?>"> or an object?
    • @weaverryan Am I working with an array? who cares!? <article id="node-{{ node.id }}"> {{ page.header }}
    • @weaverryan {{ page.header }} » The dot notation is smart! ! A. Is this an object with a public property? B. Is this an array that has this key? C. Is there a getHeader() function I can call?
    • @weaverryan Templates in the Database
    • @weaverryan Twig.js
    • @weaverryan A twig template can *also* be rendered in JavaScript
    • @weaverryan <script src="/js/twig.js">
 var template = twig({
 data: 'The {{ baked_good }} is a lie.'
 template.render({ baked_good: ‘cupcake' })
 // outputs: "The cupcake is a lie."

    • @weaverryan https://github.com/justjohn/twig.js/
    • Ryan Weaver @weaverryan ¡Gracias!