Your SlideShare is downloading. ×
TWIG: the flexible, fast and secure template language for PHP
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

TWIG: the flexible, fast and secure template language for PHP

6,222

Published on

TWIG is a template engine created by Fabien Potencier, the father of Symfony. In this talk you'll learn why he wrote it, its main features and strengths.

TWIG is a template engine created by Fabien Potencier, the father of Symfony. In this talk you'll learn why he wrote it, its main features and strengths.

Published in: Technology, Business
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
6,222
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
46
Comments
0
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. TWIG The flexible, fast, and secure template language for PHP Cesare D'Amico cesare@wyrd.it
  • 2. Cesare D'Amico freelance php dev Hi, nice to meet you! cesare@wyrd.it Twitter: __ce (double underscore) http://cesaredami.co/
  • 3. A bit of history “So, you think PHP is a templating engine?” Fabien Potencier - October 07, 2009 http://j.mp/lOnJU In his opinion, php lacks: ● concision (<?php echo $var ?>) ● template-oriented syntax (foreach()) ● reusability ● security + sandbox mode
  • 4. A bit of history Available solutions (October 2009): ● Smarty3: slow ● PHPTAL: HTML only ● ez Components: slowest, no inheritance ● Dwoo: no inheritance ● Calypso: broken (in his author's words)
  • 5. TWIG ● Fast: Twig compiles templates to plain optimized PHP code ● Secure: sandbox mode for untrusted template code ● Flexible: powered by a flexible lexer and parser, this allows to define custom tags and filters
  • 6. Assignments {% set foo = 'foo' %} {% set foo = [1, 2] %} {% set foo = ['foo': 'bar'] %} {% set foo = 'foo' ~ 'bar' %} {% set foo, bar = 'foo', 'bar' %} {% set foo %}   <div id="pagination">     ...   </div> {% endset %}
  • 7. Control structures – for {% for user in users %} {% for i in 0..10 %} {% for l in 'a'..'z' %} {% for l in 'a'|upper..'z'|upper %} {% for i in 0|range(10, 2) %}
  • 8. Control structures – for loop.index loop.index0 loop.revindex * loop.revindex0 * loop.first (boolean) loop.last *  (boolean) loop.length * loop.parent * Only for arrays and objects implementing the Countable interface
  • 9. Control structures – for <ul>   {% for user in users %}     <li>{{ user.username|e }}</li>   {% else %}     <li><em>no user found</em></li>   {% endfor %} </ul>
  • 10. Control structures – for <ul>   {% for id in users|keys %}     <li>{{ id }}</li>   {% endfor %} </ul>
  • 11. Control structures – for <ul>   {% for id, user in users %}     <li>{{ id }}: {{ user.username|e }}</li>   {% endfor %} </ul>
  • 12. Control structures – if {% if users %}   <ul>     {% for user in users %}       <li>{{ user.username|e }}</li>     {% endfor %}   </ul> {% endif %}
  • 13. Control structures – if/else {% if kenny.sick %}   Kenny is sick. {% elseif kenny.dead %}   You killed Kenny! You bastard!!! {% else %}   Kenny looks okay ­­­ so far {% endif %}
  • 14. Expressions: literals & math "Hello World" 42 / 42.23 [foo, bar] true / false none + ­ * / % // **
  • 15. Expressions: logic & comparison and or not (expression) < > <= >= == != range comparisons: {% if 1 < a < 4 %}
  • 16. Even more operators! in .. (range) | (apply filter) ~ (string concatenation) . [] (attribute access: a­la object/array) ?: (ternary operator)
  • 17. Filters: built-in date: {{ post.published_at|date("m/d/Y") }} format: “I like %s and %s” {{ string|format(foo, "bar") }} replace: “I like %this% and %that%” {{ string|format(['%this%': foo, '%that%': "bar"]) }} url_encode, json_encode, title, capitalize, upper, lower, striptags, join, reverse, length, sort, default, keys, escape / e, raw
  • 18. Tests: built-in divisibleby: {% if loop.index is divisibleby(3) %} none: {{ var is none }} even, odd
  • 19. Everyone still awake? (the best is coming...)
  • 20. Inheritance – base file <html> <head> {% block head %}   <link rel="stylesheet" href="style.css" />   <title>{% block title %}{% endblock  %}</title> {% endblock %} </head>
  • 21. Inheritance – base file <body>   <div id="content">     {% block content %}{% endblock %}   </div>   <div id="footer">     {% block footer %}     &copy; Copyright 2010 by you.     {% endblock %}   </div> </body> </html>
  • 22. Inheritance – child template {% extends "base.html" %} {% block title %}Index{% endblock %} {% block head %}   {% parent %}   <style type="text/css">     .important { color: #336699; }   </style> {% endblock %}
  • 23. Inheritance – child template {% block content %}   <h1>Index</h1>   <p class="important">     Welcome on my awesome homepage.   </p> {% endblock %}
  • 24. Dynamic & conditional inheritance {% extends some_var %} {% extends ajax_output ? "ajax.html"                        : "layout.html" %}
  • 25. include {% include 'header.html' %} ...Body... {% include 'footer.html' %} {% include 'foo' with ['foo': 'bar'] %} {% set vars = ['foo': 'bar'] %} {% include 'foo' with vars %} {% include some_var %} {% include ajax ? 'ajax.html':'base.html' %}
  • 26. Macros {% macro input(name, value, type, size) %}   <input type="{{ type|default('text') }}"      name="{{ name }}" value="{{ value|e }}"      size="{{ size|default(20) }}" /> {% endmacro %} {% macro textarea(name, value, rows) %}   <textarea name="{{ name }}"       rows="{{ rows|default(10) }}"      cols="{{ cols|default(40) }}">      {{ value|e }}   </textarea> {% endmacro %}
  • 27. Macros – calling <p>{{ _self.input('username') }}</p> <p>{{ _self.textarea(          'description',          '...',          8       ) }}</p>
  • 28. import {% import 'forms.html' as forms %} <dl>   <dt>Username</dt>   <dd>{{ forms.input('username') }}</dd>   <dt>Password</dt>   <dd>{{ forms.input('password', none,  'password') }}</dd> </dl> <p>{{ forms.textarea('comment') }}</p>
  • 29. import – hang yourself... {% macro input(name, value, type, size) %}   <input type="{{ type|default('text') }}"      name="{{ name }}" value="{{ value|e }}"      size="{{ size|default(20) }}" /> {% endmacro %} {% import _self as forms %}   <p>{{ forms.input('text','username') }}</p>
  • 30. i18n – needs gettext! {% trans "Hello World!" %}   {% trans string_var %} {% trans %}Hello World!{% endtrans %} {% trans %}Hello {{ name }}!{% endtrans %} {% trans Hello {{ name }}! %}
  • 31. i18n – plurals {% trans %}     Hey {{ name }}, I have one apple. {% plural apple_count %}     Hey {{ name }}, I have {{ count }}  apples. {% endtrans %}
  • 32. Let's use it: environment <?php require_once  '/path/to/lib/Twig/Autoloader.php'; Twig_Autoloader::register();   $loader = new  Twig_Loader_Filesystem('/path/to/templates'); $twig = new Twig_Environment($loader, array(   'cache' => '/path/to/compilation_cache', ));
  • 33. Let's use it: render <?php $template = $twig­>loadTemplate('tpl.html'); echo $template­>render(array(   'the' => 'variables',    'go' => 'here' )); Same as: $template­>display(...)
  • 34. Built-in loaders $l = new Twig_Loader_Filesystem($tplDir); $l = new Twig_Loader_Filesystem(   array($tplDir1, $tplDir2) ); Dummy: $loader = new Twig_Loader_String("..."); For unit testing: $loader = new Twig_Loader_Array($templates);
  • 35. Built-in extensions Core (automatically registered) Escaper Sandbox I18n You can create your own extensions if you need so: - implement interface Twig_ExtensionInterface - extend Twig_Extension so you need only implement needed methods $twig­>addExtension(   new Twig_Extension_Escaper() );
  • 36. Thanks everyone! ?
  • 37. 12-14 Maggio 2011 http://www.phpday.it/
  • 38. Please, rate this talk! Feel like bashing? Urge saying you fell in love with this presentation? Now you can! http://joind.in/2151

×