twig: friendly curly braces invade your templates!

97
Being dangerous with Twig

Upload: ryan-weaver

Post on 11-May-2015

797 views

Category:

Technology


1 download

DESCRIPTION

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.

TRANSCRIPT

Page 1: Twig: Friendly Curly Braces Invade Your Templates!

Being dangerous with Twig

Page 2: Twig: Friendly Curly Braces Invade Your Templates!

A guide to using Twig – the fast, secure andextensible PHP templating engine – to create clean

template code, leverage powerful filters, make your designerswrite 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 asimple {{, 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

Page 3: Twig: Friendly Curly Braces Invade Your Templates!

KnpUniversity.comgithub.com/weaverryan

• Lead for the Symfony documentation!

• KnpLabs US - Symfony consulting, training, Kumbaya!

• Writer for KnpUniversity.comscreencasts

Buenos Dias!

Page 4: Twig: Friendly Curly Braces Invade Your Templates!

Birthday Wishes!

Page 5: Twig: Friendly Curly Braces Invade Your Templates!

Happy Birthday Dad!

Page 6: Twig: Friendly Curly Braces Invade Your Templates!

Happy Birthday Anne-Sophie!

Page 7: Twig: Friendly Curly Braces Invade Your Templates!

Happy Birthday Rafael Nadal

Page 8: Twig: Friendly Curly Braces Invade Your Templates!

Happy Birthday Anderson Cooper

Page 9: Twig: Friendly Curly Braces Invade Your Templates!

Why Twig?

Act 1

Page 10: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

because template engines are awesome

Page 11: Twig: Friendly Curly Braces Invade Your Templates!

@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!') ?>

Page 12: Twig: Friendly Curly Braces Invade Your Templates!

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

Page 13: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

a template engine is a tool

Page 14: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

why not just render PHP templates?

Page 15: Twig: Friendly Curly Braces Invade Your 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

Page 16: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

we want the brevity of templates

!

with the isolation of object-oriented programming

Page 17: Twig: Friendly Curly Braces Invade Your Templates!

@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

Page 18: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Twig is concise !

and each template compiles to an actual

PHP object

Page 19: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Seeing is believing

https://www.flickr.com/photos/visitfinland/5203910918

Page 20: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

because template engines are awesome

Page 21: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

because template engines are awesome

Page 22: Twig: Friendly Curly Braces Invade Your Templates!

@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>

Page 23: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan https://www.flickr.com/photos/melolou/517629486

a moment of templating zen

Page 24: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

“The template system is meant to express presentation, not

program logic.”- Django Documentation

Page 25: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Twig can easily be used anywhere

Page 26: Twig: Friendly Curly Braces Invade Your Templates!

@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 %}

Page 27: Twig: Friendly Curly Braces Invade Your Templates!

Act 2

Twig’s Simple Life

Page 28: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Twig's three tags

Twig parses just three tags:!

» comment tag!

» print tag!

» block tag

Page 29: Twig: Friendly Curly Braces Invade Your Templates!

a. do nothing (comment tags)

{# comment #}» totally ignored when rendered

@weaverryan

Page 30: Twig: Friendly Curly Braces Invade Your Templates!

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

Page 31: Twig: Friendly Curly Braces Invade Your Templates!

@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

Page 32: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Twig’s three tags

!

» do nothing: {# comment tag #}» say something {{ ‘print tag’ }}» do something {% block tag %}

It’s just that simple!

Page 33: Twig: Friendly Curly Braces Invade Your Templates!

Act 3

Everything is an expression

Page 34: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

expressions Twig guts

» like PHP, most everything inside a tag is an expression!

!

!

!

!

» expressions are the most interesting and flexible part of Twig

Page 35: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Expressions Block names Block-specific tokens

Page 36: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

An expression can consist of many different things

https://www.flickr.com/photos/swambo/7617988518

Page 37: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

strings, numbers and variables

» like any language, strings, numbers and variables are commonplace

Page 38: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

arrays and hashes

» arrays use [], hashes use {}

Page 39: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

operators

» just like PHP operators, but extensible

Page 40: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

filters

» filters modify the value that precedes it and are always preceded by a pipe (|)

» filters may or may not take arguments

Page 41: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

functions

» returns a value based on an arbitrary input

Page 42: Twig: Friendly Curly Braces Invade Your Templates!

@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

Page 43: Twig: Friendly Curly Braces Invade Your Templates!

Act 4

Twig on the battlefield

Page 44: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

» a template that displays a list of “widgets” in odd-even rows

» render info about each widget

» create basic, clean pagination

the test…

Page 45: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Page 46: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan http

://1.

bp.b

logs

pot.c

om/_

D_Z-

D2tz

i14/

TBpO

nhVq

yAI/A

AAAA

AAAD

FU/8

tfM4E

_Z4p

U/s

1600

/resp

onsi

bilit

y12(

alte

rnat

e).p

ng

Page 47: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Page 48: Twig: Friendly Curly Braces Invade Your Templates!

@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…

Page 49: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan http

://1.

bp.b

logs

pot.c

om/_

D_Z-

D2tz

i14/

TBpO

nhVq

yAI/A

AAAA

AAAD

FU/8

tfM4E

_Z4p

U/s

1600

/resp

onsi

bilit

y12(

alte

rnat

e).p

ng

Page 50: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Page 51: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan https://www.flickr.com/photos/circasassy/7192588208

Flex some filters

Page 52: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Page 53: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

convenience, readability

Page 54: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Page 55: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

pagination?

Page 56: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Page 57: Twig: Friendly Curly Braces Invade Your Templates!

@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!

Page 58: Twig: Friendly Curly Braces Invade Your Templates!

Act 5

Twig extensions!

Page 59: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

» filters» functions» operators» tests (e.g. divisibleby)» custom tags

Twig extensions

everything in Twig is loaded by an “Extension” class:

Extensions are easy!

Page 60: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Page 61: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Yes, there is a missing piece of “hooking this up”

Page 62: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

It’s a small amount of code, involving services

Page 63: Twig: Friendly Curly Braces Invade Your Templates!

@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

Page 64: Twig: Friendly Curly Braces Invade Your Templates!

Act 6

Theming D7 versus D8

Page 65: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Good News!

Page 66: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

The Changes are Underwhelming!

Page 67: Twig: Friendly Curly Braces Invade Your Templates!

@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

Page 68: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

<div id="node-<?php print $node->nid; ?>" clearfix"<?php print $attributes; ?>> <?php print render($title_prefix); ?> <div class="content clearfix"<?php print $content_attributes; ?>> <?php hide($content['links']); print render($content); ?> </div> <?php $links = render($content['links']); if ($links): ?> <div class="link-wrapper"> <?php print $links; ?> </div> <?php endif; ?> </div>

D7: node.tpl.php

Page 69: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

<article id="node-{{ node.id }}” role=“article" {{ attributes|without(‘id', 'role') }}> <header>{{ title_prefix }}</header> <div class="content clearfix"{{ content_attributes }}> {{ content|without('links') }} </div> {% if content.links %} <footer class="link-wrapper"> {{ content.links }} </footer> {% endif %}</article>

D8: node.html.twig

Page 70: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Function overrides

Page 71: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

D7: template.php

function bartik_field__taxonomy_term_reference($variables) { $output = ''; // Render the label, if it's not hidden. if (!$variables['label_hidden']) { $output .= '<h3 class="field-label">' . $variables['label'] . ': </h3>'; } // Render the items. $output .= ($variables['element']['#label_display'] == 'inline') ? '<ul class="links inline">' : '<ul class="links">'; foreach ($variables['items'] as $delta => $item) { $output .= '<li class="taxonomy-term-reference-' . $delta . '"' . $variables['item_attributes'][$delta] . '>' . drupal_render($item) . '</li>'; } $output .= '</ul>';

Page 72: Twig: Friendly Curly Braces Invade Your Templates!

@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 %} </ul> </div>

Page 73: Twig: Friendly Curly Braces Invade Your Templates!

Act 7

after-dinner mint

Mmmmm…..

Page 74: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Debugging

Page 75: Twig: Friendly Curly Braces Invade Your Templates!

@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;

Page 76: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

… inline suggestions about the template to override …

Page 77: Twig: Friendly Curly Braces Invade Your Templates!
Page 78: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

… dump *all* variables you have access to …

Page 79: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

<article id="node-{{ node.id }}" ...> {{ dump() }} {# ... #}</article>

Page 80: Twig: Friendly Curly Braces Invade Your Templates!
Page 81: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

… or just dump the names of the variables …

Page 82: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

<article ...> {{ dump(_context|keys) }} </article>

Page 83: Twig: Friendly Curly Braces Invade Your Templates!
Page 84: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Inheritance

Page 85: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

{% block header %}<header> {{ title_prefix }} {% if not page %} <h2{{ title_attributes }}> <a href="{{ node_url }}">{{ label }}</a> </h2> {% endif %} {{ title_suffix }} {% if display_submitted %} <div class="meta submitted"> {{ user_picture }} {{ submitted }} </div> {% endif %}</header>{% endblock %}

node.html.twig

Page 86: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

{% extends "core/themes/bartik/templates/node.html.twig" %}{% block header %} <h1 class="header">{{ label }}</h1>{% endblock %}

node--article.html.twig

Page 87: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

{% extends "core/themes/bartik/templates/node.html.twig" %}{% block header %} <div class="article"> {{ parent() }} </div>{% endblock %}

node--article.html.twig

Page 88: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

dot.notation

Page 89: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Am I working with an array?

<?php print render($page['header']); ?>

<div id="node-<?php print $node->nid; ?>">

or an object?

Page 90: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Am I working with an array?

who cares!?

<article id="node-{{ node.id }}">

{{ page.header }}

Page 91: Twig: Friendly Curly Braces Invade Your Templates!

@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?

Page 92: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Templates in the Database

Page 93: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

Twig.js

Page 94: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

A twig template can *also* be rendered in

JavaScript

Page 95: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

<script src="/js/twig.js"> <script> var template = twig({ data: 'The {{ baked_good }} is a lie.' }); console.log( template.render({ baked_good: ‘cupcake' }) ); // outputs: "The cupcake is a lie."</script>

Page 96: Twig: Friendly Curly Braces Invade Your Templates!

@weaverryan

https://github.com/justjohn/twig.js/

Page 97: Twig: Friendly Curly Braces Invade Your Templates!

Ryan Weaver @weaverryan

¡Gracias!