Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Extending Twig
Gerry Vandermaesen
About me
• @gerryvdm 🐦
• Web developer at King Foo 🐵 (Intracto Group)
• SensioLabs Certified Symfony Developer 👑
• Drupal n...
Twig Templating Engine
• Fast 🏃
• Secure 🔑
• Flexible 🐍
• Replaces PHPTemplate in D8 👏
Basic syntax
<h1>{{ article.title }}</h1>



<p>Published on {{ article.createdAt | date('d/m/Y') }}</p>



{% if article....
Some cool Twig features
Template inheritance
{# parent.html.twig #}

<!doctype html>

<html>

<head>

<title>

{% block title %}DUG Belgium{% endb...
Template inheritance
{# child.html.twig #}



{% extends "parent.html.twig" %}



{% block title %}Blog - {{ parent() }}{%...
Template inheritance
{# grandchild.html.twig #}



{% extends "child.html.twig" %}



{% block content %}

<h3>{{ post.tit...
Functions
{# get a PHP constant #}

{{ constant("SomeClassName::CONSTANT_NAME") }}



{# dump a variable's content #}

{{ ...
Filters
{{ "some random title" | title }}

{# outputs "Some Random Title" #}
{{ "now" | date_modify("+1 day") | date("d/m/...
Tags
{% spaceless %}

<h2>

Lorem ipsum

</h2>

{% endspaceless %}



{# outputs "<h2>Lorem ipsum</h2>" #}
Macros
{# macros.html.twig #}



{% macro link_email(email, label) %}

<a href="mailto:{{ email }}">

{{- label | default(...
Extending Twig
General workflow
• Implement an extension (extend Twig_Extension)
• Register the extension in the Twig environment
• Profit ...
Writing an extension
<?php



// modules/twig_demo/src/Twig/ExampleExtension.php



namespace Drupaltwig_demoTwig;



clas...
Registering the extension
# modules/twig_demo/twig_demo.services.yml



services:

twig.example_extension:

class: Drupalt...
Adding custom functions
<?php



class ExampleExtension extends Twig_Extension

{

public function getFunctions()

{

retu...
Invoking our function
<p>
<img src="{{ gravatar('gerry@king-foo.be', 50) }}”>
</p>
Adding custom filters
<?php



class ExampleExtension extends Twig_Extension

{

public function getFilters()

{



return ...
Invoking our filter
<p>
{{ "Hello, world. Goodbye, world!”
| highlight('world') }}
</p>
Adding global variables
<?php



class ExampleExtension extends Twig_Extension

{

private $container;



public function ...
Using our globals
<p>Pi ~= {{ pi | round(6) }}</p>


<p>{{ modules | join(', ') }}</p>
Defining custom tests
<?php



class ExampleExtension extends Twig_Extension

{

public function getTests()

{

return arra...
Using our custom test
{% if '2015-06-25' is today %}

<p>It is Drupal User Group meeting today</p>

{% endif %}



{% if '...
Defining custom tags
<?php



class ExampleExtension extends Twig_Extension

{

public function getTokenParsers()

{

retur...
Writing a token parser
<?php



namespace Drupaltwig_demoTwig;



class MarkdownTokenParser extends Twig_TokenParser

{

p...
Writing a node class
<?php



namespace Drupaltwig_demoTwig;



class MarkdownNode extends Twig_Node

{

public function _...
Questions?
• https://github.com/gerryvdm/dug
• http://www.slideshare.net/gerryvdm/extending-twig
Upcoming SlideShare
Loading in …5
×

Extending Twig

1,423 views

Published on

Extending Twig for Drupal 8

Published in: Software
  • Be the first to comment

Extending Twig

  1. 1. Extending Twig Gerry Vandermaesen
  2. 2. About me • @gerryvdm 🐦 • Web developer at King Foo 🐵 (Intracto Group) • SensioLabs Certified Symfony Developer 👑 • Drupal noob 😟
  3. 3. Twig Templating Engine • Fast 🏃 • Secure 🔑 • Flexible 🐍 • Replaces PHPTemplate in D8 👏
  4. 4. Basic syntax <h1>{{ article.title }}</h1>
 
 <p>Published on {{ article.createdAt | date('d/m/Y') }}</p>
 
 {% if article.summary %}
 <p>{{ article.summary }}</p>
 {% endif %}
 
 <div>{{ article.content }}</div>
 
 <ul class="tags">
 {% for tag in article.tags %}
 <li>{{ tag }}</li>
 {% endfor %}
 </ul>
  5. 5. Some cool Twig features
  6. 6. Template inheritance {# parent.html.twig #}
 <!doctype html>
 <html>
 <head>
 <title>
 {% block title %}DUG Belgium{% endblock %}
 </title>
 </head>
 
 <body>
 {% block body %}{% endblock %}
 </body>
 </html>
  7. 7. Template inheritance {# child.html.twig #}
 
 {% extends "parent.html.twig" %}
 
 {% block title %}Blog - {{ parent() }}{% endblock %}
 
 {% block body %}
 <h1>Blog</h1>
 {% block content %}{% endblock %}
 {% endblock %}
  8. 8. Template inheritance {# grandchild.html.twig #}
 
 {% extends "child.html.twig" %}
 
 {% block content %}
 <h3>{{ post.title }}</h3>
 <div>{{ post.content }}</div>
 {% endblock %}

  9. 9. Functions {# get a PHP constant #}
 {{ constant("SomeClassName::CONSTANT_NAME") }}
 
 {# dump a variable's content #}
 {{ dump(foo) }}
 
 {# get random element #}
 {{ random(["apple", "banana"]) }}
  10. 10. Filters {{ "some random title" | title }}
 {# outputs "Some Random Title" #} {{ "now" | date_modify("+1 day") | date("d/m/Y") }}
 {# outputs "26/06/2016" #}
 
 {% set fruits = ["banana", "apple", "pear", "kiwi"] %}
 {{ fruits | slice(1, 2) | join(", ") }}
 {# outputs "apple, pear" #}
 
 {{ "combo chain" | upper | lower | upper | lower | upper }}
 {# outputs "COMBO CHAIN" #}
  11. 11. Tags {% spaceless %}
 <h2>
 Lorem ipsum
 </h2>
 {% endspaceless %}
 
 {# outputs "<h2>Lorem ipsum</h2>" #}
  12. 12. Macros {# macros.html.twig #}
 
 {% macro link_email(email, label) %}
 <a href="mailto:{{ email }}">
 {{- label | default(email) -}}
 </a>
 {% endmacro %}
 
 
 {# foo.html.twig #}
 
 {% import "macros.html.twig" as macro %}
 
 <p>Contact me at
 {{ macro.link_email("gerry@king-foo.be") }}</p>

  13. 13. Extending Twig
  14. 14. General workflow • Implement an extension (extend Twig_Extension) • Register the extension in the Twig environment • Profit 💰 💰 💰
  15. 15. Writing an extension <?php
 
 // modules/twig_demo/src/Twig/ExampleExtension.php
 
 namespace Drupaltwig_demoTwig;
 
 class ExampleExtension extends Twig_Extension
 {
 public function getName()
 {
 return 'example';
 }
 }
  16. 16. Registering the extension # modules/twig_demo/twig_demo.services.yml
 
 services:
 twig.example_extension:
 class: Drupaltwig_demoTwigExampleExtension
 tags:
 - { name: twig.extension }
  17. 17. Adding custom functions <?php
 
 class ExampleExtension extends Twig_Extension
 {
 public function getFunctions()
 {
 return array(
 new Twig_SimpleFunction( 'gravatar', array($this, ‘generateGravatarUrl') )
 );
 }
 
 public function generateGravatarUrl($email, $size = 100)
 {
 return sprintf('http://www.gravatar.com/avatar/%s?s=%s',
 md5($email),
 $size
 );
 }
 }
  18. 18. Invoking our function <p> <img src="{{ gravatar('gerry@king-foo.be', 50) }}”> </p>
  19. 19. Adding custom filters <?php
 
 class ExampleExtension extends Twig_Extension
 {
 public function getFilters()
 {
 
 return array(
 new Twig_SimpleFilter(
 'highlight', array($this, 'highlight'), array('is_safe' => array('html' => true))
 )
 );
 }
 
 public function highlight($subject, $search)
 {
 $highlighted = sprintf('<span style="background: yellow; font-weight: bold;">%s</span>', $search);
 
 return str_replace($search, $highlighted, $subject);
 }
 }
  20. 20. Invoking our filter <p> {{ "Hello, world. Goodbye, world!” | highlight('world') }} </p>
  21. 21. Adding global variables <?php
 
 class ExampleExtension extends Twig_Extension
 {
 private $container;
 
 public function __construct(ContainerInterface $container)
 {
 $this->container = $container;
 }
 
 public function getGlobals()
 {
 return array(
 'pi' => M_PI,
 'modules' => array_keys(
 $this->container->getParameter('container.modules')
 )
 );
 }
 }
  22. 22. Using our globals <p>Pi ~= {{ pi | round(6) }}</p> 
 <p>{{ modules | join(', ') }}</p>
  23. 23. Defining custom tests <?php
 
 class ExampleExtension extends Twig_Extension
 {
 public function getTests()
 {
 return array(
 new Twig_SimpleTest('today', array($this, 'testIfToday'))
 );
 }
 
 public function testIfToday($value)
 {
 $today = new DateTime('now');
 
 if (!$value instanceof DateTimeInterface) {
 $value = new DateTime($value);
 }
 
 return $value->format('Y-m-d') === $today->format('Y-m-d');
 }
 }

  24. 24. Using our custom test {% if '2015-06-25' is today %}
 <p>It is Drupal User Group meeting today</p>
 {% endif %}
 
 {% if '2015-12-25' is today %}
 <p>It is Christmas today</p>
 {% endif %}
  25. 25. Defining custom tags <?php
 
 class ExampleExtension extends Twig_Extension
 {
 public function getTokenParsers()
 {
 return array(
 new MarkdownTokenParser()
 );
 }
 }

  26. 26. Writing a token parser <?php
 
 namespace Drupaltwig_demoTwig;
 
 class MarkdownTokenParser extends Twig_TokenParser
 {
 public function parse(Twig_Token $token)
 {
 $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
 $body = $this->parser->subparse(array($this, 'decideMarkdownEnd'), true);
 $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
 
 return new MarkdownNode($body, $token->getLine(), $this->getTag());
 }
 
 public function decideMarkdownEnd(Twig_Token $token)
 {
 return $token->test('endmarkdown');
 }
 
 public function getTag()
 {
 return 'markdown';
 }
 }
  27. 27. Writing a node class <?php
 
 namespace Drupaltwig_demoTwig;
 
 class MarkdownNode extends Twig_Node
 {
 public function __construct(Twig_NodeInterface $body, $line, $tag = 'markdown')
 {
 parent::__construct(array('body' => $body), array(), $line, $tag);
 }
 
 public function compile(Twig_Compiler $compiler)
 {
 $compiler
 ->addDebugInfo($this)
 ->write("ob_start();n")
 ->subcompile($this->getNode('body'))
 ->write("echo MichelfMarkdown::defaultTransform(ob_get_clean()); n")
 ;
 }
 }
  28. 28. Questions?
  29. 29. • https://github.com/gerryvdm/dug • http://www.slideshare.net/gerryvdm/extending-twig

×