SlideShare a Scribd company logo
TWIG




Saturday, 3 November, 12
ABOUT ME




                    Team lead at FreshBooks

                    Lead Developer of CakePHP

                    Contributor to Twig




Saturday, 3 November, 12
WHAT IS IT




                    Templating language for PHP.

                    Uses syntax and ideas from jinja2.

                    Flexible and extensible at every layer.




Saturday, 3 November, 12
BUT PHP IS A
                             TEMPLATING
                           LANGUAGE DUMMY



Saturday, 3 November, 12
PHP SUCKS FOR TEMPLATING
             // In         Plain PHP
             <?php         echo $var; ?> (XSS you lose)
             <?php         echo htmlspecialchars($var, ENT_QUOTES, ‘UTF-8’); ?>
             <?php         echo h($var); ?> (sugar for htmlentities)

             // In Twig - autoescaping enabled
             {{ var }}




Saturday, 3 November, 12
BENEFITS OF TWIG



                    Terse syntax, and sugar.

                    Automatic HTML escaping.

                    Sandbox mode, which enables user editable templates.

                    Ability to create custom DSL’s using application tags, operators
                    and functions.




Saturday, 3 November, 12
PLAIN PHP VS TWIG




Saturday, 3 November, 12
CONDITIONALS

             // In Plain PHP
             <?php if (!empty($var): ?>
             ...
             <?php endif; ?>

             // In Twig
             {% if var %}
             ...
             {% endif %}




Saturday, 3 November, 12
LOOPS

             <?php
             if (!empty($var):
               foreach ((array)$var as $i => $v):
                 printf(
                     ‘%s : %s’,
                     htmlspecialchars($i, ENT_QUOTES, ‘UTF-8’),
                     htmlspecialchars($v, ENT_QUOTES, ‘UTF-8’));
               endforeach;
             else:
               echo ‘No things’;
             endif;




Saturday, 3 November, 12
LOOPS

             {%      for i, v in var %}
             {{      i }} : {{ v }}
             {%      else %}
             No      things
             {%      endfor %}




Saturday, 3 November, 12
LOOPS

             {%      for user in users if user.active %}
             {{      user.name }} : {{ user.email }}
             {%      else %}
             No      active users
             {%      endfor %}




Saturday, 3 November, 12
BUT WAIT THERE IS
                                MORE




Saturday, 3 November, 12
AWESOME++




                    Macros.

                    Blocks & extending templates.




Saturday, 3 November, 12
MACROS

             {% macro username(user) %}
             <a href=”{{ url({
               ‘controller’: ‘users’,
               ‘action’: ‘view’,
               user.username) }}”>
                 <span class=”user-first-name”>
                 {{ user.first_name }}
                 </span>
                 <span> class=”user-last-name”>
                 {{ user.last_name }}
                 </span>
               </a>
             {% endmacro %}




Saturday, 3 November, 12
IMPORTING MACROS

             // import all the macros
             {% import ‘/import/formatting.twig’ as formatting %}
             {{ formatting.username(user) }}

             // import one macro
             {% from ‘/import/formatting.twig’ import username %}
             {{ username(user) }}

             // import one & alias it.
             {% from ‘/import/formatting.twig’ import username as un %}
             {{ un(user) }}




Saturday, 3 November, 12
INHERITANCE & BLOCKS



                    Extending views & blocks work hand in hand.

                    Blocks are like slots or holes in a template, that the child can fill.

                    Blocks can be used out of order, which is pretty sweet.

                    Blocks can be imported from other templates, similar to traits.




Saturday, 3 November, 12
INHERITANCE

             {# layout/base.twig #}

             Company X - Official Email template

             {% block content ‘Super important’ %}

             Copyright 2012




Saturday, 3 November, 12
INHERITANCE

             {# email/winner.twig #}
             {% extend ‘/layout/base.twig’ %}

             {% block content %}
             To whom it may concern,

             You win!
             {% endblock %}




Saturday, 3 November, 12
INHERITANCE

             {# email/winner.twig #}
             {% extend ‘/layout/base.twig’ %}

             {% block content %}
             To whom it may concern,

             {{ parent() }} You win!

             {% endblock %}




Saturday, 3 November, 12
INHERITANCE TIPS




                    Don’t use {% block %} inside a loop. It doesn’t do what you
                    want.

                    You can use {{ block(name) }} to dynamically call blocks.




Saturday, 3 November, 12
EXTENDING TWIG
                               TWIG EXTENSIONS




Saturday, 3 November, 12
EXTENDING TWIG



                    Twig can be extended in several ways.

                           Filters, Functions, Globals, Tests, Operators, TokenParsers,
                           NodeVisitors.

                    You should use extensions to package up your enhancements.




Saturday, 3 November, 12
TWIG EXTENSIONS




Saturday, 3 November, 12
LOADING EXTENSIONS

              $loader = new Twig_Loader_FileSystem(APP . ‘/templates’);
              $twig = new Twig_Environment($loader, $options);
              $twig->addExtension(new App_Extension_Url());




Saturday, 3 November, 12
ENVIRONMENT FACTORY

              class AppTwig {
                static function loadTemplate($template, $options = array()) {
                  $loader = new Twig_Loader_FileSystem(APP . ‘/templates’);
                  $twig = new Twig_Environment($loader, $options);
                  $twig->addExtension(new App_Extension_Url());
                  // Load more extensions
                  return $twig->loadTemplate($template);
                }
              }

              $template = AppTwig::loadTemplate(‘/users/profile.twig’);




Saturday, 3 November, 12
EXTENSION EXAMPLE
              <?php
              class App_Extension_Url extends Twig_Extension {
                public function getName() {
                  return ‘app.url’;
                }

                  public function getFilters() {
                    return array(
                       ‘name’ => new Twig_Filter_Method($this, ‘formatName’),
                    );
                  }
              }




Saturday, 3 November, 12
GLOBALS



                    Can be used to expose application or framework objects.

                    Great for migrating an older codebase to use Twig.

                    E.g {{ html.link(...) }}




Saturday, 3 November, 12
FUNCTIONS



                    Global functions added to a template context.

                    Great for providing shortcuts to application features, like url
                    generation or built-in PHP functions.

                    Example {{ form_input(model, ‘name’) }}




Saturday, 3 November, 12
FILTERS



                     Filters are intended for simple formatting functions.

                     The filtered variable is the first argument to the filter function.

                     Filters can have additional arguments as well.

                     Example: {{ invoice.amount|currency(‘CAD’) }}




Saturday, 3 November, 12
TESTS


                    Allow you to implement custom conditional logic. In an
                    expressive manner with domain objects.

                    Value being compared is supplied as the first argument. Other
                    arguments follow.

                    {% if user is paying %}
                    {% if number is divisibleby(3) %}




Saturday, 3 November, 12
NODE VISITORS



                    Allows you to visit each node in the Abstract syntax tree.

                    Applied before template is compiled.

                    Commonly used for optimizing the AST, or applying
                    transformations to, or reading data from nodes in the tree.




Saturday, 3 November, 12
CUSTOM TAGS




Saturday, 3 November, 12
TWIG INTERNALS


          ENVIRONMENT




                 LOADER




Saturday, 3 November, 12
TWIG INTERNALS


          ENVIRONMENT         LEXER




                 LOADER




Saturday, 3 November, 12
TWIG INTERNALS


          ENVIRONMENT         LEXER




                 LOADER               TOKENS




Saturday, 3 November, 12
TWIG INTERNALS


          ENVIRONMENT         LEXER            PARSER




                 LOADER               TOKENS




Saturday, 3 November, 12
TWIG INTERNALS


          ENVIRONMENT         LEXER            PARSER




                 LOADER               TOKENS            NODES




Saturday, 3 November, 12
TWIG INTERNALS


          ENVIRONMENT         LEXER            PARSER           COMPILER




                 LOADER               TOKENS            NODES




Saturday, 3 November, 12
TWIG INTERNALS


          ENVIRONMENT         LEXER            PARSER           COMPILER




                 LOADER               TOKENS            NODES




                                                           PHP CODE




Saturday, 3 November, 12
TOKEN PARSERS


                    Used to implement custom tags or DSL features.

                    The most complex feature to add.

                    Each tag is composed of two parts:

                           TokenParser - parses the tag and validates its syntax.

                           Node - Added to the AST and compiles the PHP code used
                           in templates.




Saturday, 3 November, 12
TAG EXAMPLE


         {% debug %}

         {% debug my_var %}

         {% debug 2 > 1 %}




Saturday, 3 November, 12
TOKEN PARSER
         class App_TokenParser_Debug extends Twig_TokenParser {

              public function parse(Twig_Token $token) {
                $line = $token->getLine();
                $expr = null;
                if (!$this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE)) {
                   $expr = $this->parser->getExpressionParser->parseExpression();
                }
                $this->parse->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
                return new App_Node_Debug($expr, $line, $this->getTag());
              }

         }




Saturday, 3 November, 12
NODE COMPILER
         class App_Node_Debug extends Twig_Node {

              public function __construct(Twig_Node_Expression $ex, $line, $tag) {
                parent::__construct(array(‘expr’ => $ex), $line, $tag);
              }

              public function compile(Twig_Compiler $compiler) {
                $compiler->write(‘if ($this->env->isDebug()) {‘);
                if ($this->getNode(‘expr’) === null) {
                   // Print all vars.
                } else {
                   $compiler->write(‘var_dump(‘)
                     ->subcompile($this->getNode(‘expr’))
                     ->raw(‘);’);
                }
                $compiler->write(‘}’);
              }

         }




Saturday, 3 November, 12
OPERATORS




                    Allow you to add additional boolean operators.

                    I’ve never used this feature.




Saturday, 3 November, 12
DEPLOYING TWIG




Saturday, 3 November, 12
TWIG IN PRODUCTION




                    FreshBooks (the app, not the website).

                    520+ templates.

                    Twig templates are used for almost all HTML & E-mail content.




Saturday, 3 November, 12
TEMPLATE COMPILATION




                           TWIG




Saturday, 3 November, 12
TEMPLATE COMPILATION




                           TWIG    PHP




Saturday, 3 November, 12
TEMPLATE COMPILATION




                           TWIG    PHP      HTML




Saturday, 3 November, 12
TEMPLATE COMPILATION




                           TWIG      PHP          HTML

                                  Saved to disk




Saturday, 3 November, 12
TEMPLATE COMPILATION




                                     PHP          HTML

                                  Saved to disk




Saturday, 3 November, 12
HOW WE DEPLOY




Saturday, 3 November, 12
HOW WE DEPLOY



                 COPY
                 FILES




Saturday, 3 November, 12
HOW WE DEPLOY



                 COPY         COMPILE
                 FILES        / BUILD




Saturday, 3 November, 12
HOW WE DEPLOY



                 COPY         COMPILE
                                           SYMLINK
                 FILES        / BUILD




Saturday, 3 November, 12
PRECOMPILE SCRIPT
              $directory = new RecursiveDirectoryIterator($argv[0]);
              $recurser = new RecursiveIteratorIterator($directory);
              $matcher = new RegexIterator(
                $recurser,
                '/.*?.twig$/',
                RegexIterator::GET_MATCH);

              echo "Compiling Templatesn";

              $i = 0;
              foreach ($matcher as $file) {
                $filename = str_replace($argv[1], '', $file[0]);
                AppTwig::loadTemplate('/' . $filename);
                echo '.';
                $i++;
              }
              echo "nTemplates compiledn";
              exit(0);


Saturday, 3 November, 12
TWIG C EXTENSION



                    You can also install ext/twig.

                    This pushes the most frequently used method
                    Twig_Template::getAttribute() into C which increases
                    performance considerably.

                    The C extension is in the Twig repository.




Saturday, 3 November, 12
QUESTIONS?




Saturday, 3 November, 12
THANKS
                               @MARK_STORY
                           HTTP://MARK-STORY.COM




Saturday, 3 November, 12

More Related Content

What's hot

LES JOINTURES
LES JOINTURESLES JOINTURES
LES JOINTURES
danaobrest
 
Diagrammes de classes
Diagrammes de classesDiagrammes de classes
Diagrammes de classes
Mireille Blay-Fornarino
 
Roy Osherove on Unit Testing Good Practices and Horrible Mistakes
Roy Osherove on Unit Testing Good Practices and Horrible MistakesRoy Osherove on Unit Testing Good Practices and Horrible Mistakes
Roy Osherove on Unit Testing Good Practices and Horrible MistakesRoy Osherove
 
Création de Services et Configuration du ESB avec TalendESB
Création de Services et Configuration du ESB avec TalendESBCréation de Services et Configuration du ESB avec TalendESB
Création de Services et Configuration du ESB avec TalendESB
Lilia Sfaxi
 
Fiche de TP 3 sur les bases de données avec les SGBD(Système de Gestion des B...
Fiche de TP 3 sur les bases de données avec les SGBD(Système de Gestion des B...Fiche de TP 3 sur les bases de données avec les SGBD(Système de Gestion des B...
Fiche de TP 3 sur les bases de données avec les SGBD(Système de Gestion des B...
ATPENSC-Group
 
Talend ESB : Monitoring, Repartition de Charge et Authentification
Talend ESB : Monitoring, Repartition de Charge et AuthentificationTalend ESB : Monitoring, Repartition de Charge et Authentification
Talend ESB : Monitoring, Repartition de Charge et Authentification
Lilia Sfaxi
 
Atelier Python 2eme partie par Achraf Kacimi El Hassani
Atelier Python 2eme partie par Achraf Kacimi El HassaniAtelier Python 2eme partie par Achraf Kacimi El Hassani
Atelier Python 2eme partie par Achraf Kacimi El HassaniShellmates
 
1 java introduction
1 java introduction1 java introduction
1 java introduction
abdullah al mahamud rosi
 
Architectures 3-tiers (Web)
Architectures 3-tiers (Web)Architectures 3-tiers (Web)
Architectures 3-tiers (Web)
Heithem Abbes
 
Examen de-passage-developpement-informatiques-tsdi-2015-synthese-variante-1-o...
Examen de-passage-developpement-informatiques-tsdi-2015-synthese-variante-1-o...Examen de-passage-developpement-informatiques-tsdi-2015-synthese-variante-1-o...
Examen de-passage-developpement-informatiques-tsdi-2015-synthese-variante-1-o...
abdelghani04
 
Ingénierie du test 0.9
Ingénierie du test 0.9Ingénierie du test 0.9
Ingénierie du test 0.9
Stéphane Salmons
 
Support JEE Spring Inversion de Controle IOC et Spring MVC
Support JEE Spring Inversion de Controle IOC et Spring MVCSupport JEE Spring Inversion de Controle IOC et Spring MVC
Support JEE Spring Inversion de Controle IOC et Spring MVC
ENSET, Université Hassan II Casablanca
 
Cours JavaScript
Cours JavaScriptCours JavaScript
Cours JavaScript
Olivier Le Goaër
 
cour de compilation
cour de compilation cour de compilation
cour de compilation Ens Kouba
 
Les limites-de-l uml (1)
Les limites-de-l uml (1)Les limites-de-l uml (1)
Les limites-de-l uml (1)
Samah Dekhil
 
Présentation de JEE et de son écosysteme
Présentation de JEE et de son écosystemePrésentation de JEE et de son écosysteme
Présentation de JEE et de son écosysteme
Stéphane Traumat
 
Tp2 - WS avec JAXRS
Tp2 - WS avec JAXRSTp2 - WS avec JAXRS
Tp2 - WS avec JAXRS
Lilia Sfaxi
 

What's hot (20)

LES JOINTURES
LES JOINTURESLES JOINTURES
LES JOINTURES
 
Diagrammes de classes
Diagrammes de classesDiagrammes de classes
Diagrammes de classes
 
Middleware
MiddlewareMiddleware
Middleware
 
Roy Osherove on Unit Testing Good Practices and Horrible Mistakes
Roy Osherove on Unit Testing Good Practices and Horrible MistakesRoy Osherove on Unit Testing Good Practices and Horrible Mistakes
Roy Osherove on Unit Testing Good Practices and Horrible Mistakes
 
Création de Services et Configuration du ESB avec TalendESB
Création de Services et Configuration du ESB avec TalendESBCréation de Services et Configuration du ESB avec TalendESB
Création de Services et Configuration du ESB avec TalendESB
 
Fiche de TP 3 sur les bases de données avec les SGBD(Système de Gestion des B...
Fiche de TP 3 sur les bases de données avec les SGBD(Système de Gestion des B...Fiche de TP 3 sur les bases de données avec les SGBD(Système de Gestion des B...
Fiche de TP 3 sur les bases de données avec les SGBD(Système de Gestion des B...
 
Talend ESB : Monitoring, Repartition de Charge et Authentification
Talend ESB : Monitoring, Repartition de Charge et AuthentificationTalend ESB : Monitoring, Repartition de Charge et Authentification
Talend ESB : Monitoring, Repartition de Charge et Authentification
 
Atelier Python 2eme partie par Achraf Kacimi El Hassani
Atelier Python 2eme partie par Achraf Kacimi El HassaniAtelier Python 2eme partie par Achraf Kacimi El Hassani
Atelier Python 2eme partie par Achraf Kacimi El Hassani
 
1 java introduction
1 java introduction1 java introduction
1 java introduction
 
Architectures 3-tiers (Web)
Architectures 3-tiers (Web)Architectures 3-tiers (Web)
Architectures 3-tiers (Web)
 
Examen de-passage-developpement-informatiques-tsdi-2015-synthese-variante-1-o...
Examen de-passage-developpement-informatiques-tsdi-2015-synthese-variante-1-o...Examen de-passage-developpement-informatiques-tsdi-2015-synthese-variante-1-o...
Examen de-passage-developpement-informatiques-tsdi-2015-synthese-variante-1-o...
 
Plsql
PlsqlPlsql
Plsql
 
Ingénierie du test 0.9
Ingénierie du test 0.9Ingénierie du test 0.9
Ingénierie du test 0.9
 
Support JEE Spring Inversion de Controle IOC et Spring MVC
Support JEE Spring Inversion de Controle IOC et Spring MVCSupport JEE Spring Inversion de Controle IOC et Spring MVC
Support JEE Spring Inversion de Controle IOC et Spring MVC
 
Cours access
Cours accessCours access
Cours access
 
Cours JavaScript
Cours JavaScriptCours JavaScript
Cours JavaScript
 
cour de compilation
cour de compilation cour de compilation
cour de compilation
 
Les limites-de-l uml (1)
Les limites-de-l uml (1)Les limites-de-l uml (1)
Les limites-de-l uml (1)
 
Présentation de JEE et de son écosysteme
Présentation de JEE et de son écosystemePrésentation de JEE et de son écosysteme
Présentation de JEE et de son écosysteme
 
Tp2 - WS avec JAXRS
Tp2 - WS avec JAXRSTp2 - WS avec JAXRS
Tp2 - WS avec JAXRS
 

Similar to Introduction to Twig

Objects, Testing, and Responsibility
Objects, Testing, and ResponsibilityObjects, Testing, and Responsibility
Objects, Testing, and Responsibility
machuga
 
Wordpress Plugin Development Practices
Wordpress Plugin Development PracticesWordpress Plugin Development Practices
Wordpress Plugin Development Practices
serversideup
 
Symfony2 and MongoDB - MidwestPHP 2013
Symfony2 and MongoDB - MidwestPHP 2013   Symfony2 and MongoDB - MidwestPHP 2013
Symfony2 and MongoDB - MidwestPHP 2013
Pablo Godel
 
Effective PHP. Part 3
Effective PHP. Part 3Effective PHP. Part 3
Effective PHP. Part 3
Vasily Kartashov
 
Elasticsearch in 15 minutes
Elasticsearch in 15 minutesElasticsearch in 15 minutes
Elasticsearch in 15 minutes
David Pilato
 
Twig Brief, Tips&Tricks
Twig Brief, Tips&TricksTwig Brief, Tips&Tricks
Twig Brief, Tips&Tricks
Andrei Burian
 
Building maintainable javascript applications
Building maintainable javascript applicationsBuilding maintainable javascript applications
Building maintainable javascript applications
equisodie
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
Alena Holligan
 
Questions On The Code And Core Module
Questions On The Code And Core ModuleQuestions On The Code And Core Module
Questions On The Code And Core Module
Katie Gulley
 
Doctrine in FLOW3
Doctrine in FLOW3Doctrine in FLOW3
Doctrine in FLOW3
Karsten Dambekalns
 
If you have a problem, if no one else can help... and if you can find them, m...
If you have a problem, if no one else can help... and if you can find them, m...If you have a problem, if no one else can help... and if you can find them, m...
If you have a problem, if no one else can help... and if you can find them, m...
bitcoder
 
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching logging
Tricode (part of Dept)
 
Basics of Metaprogramming in Ruby
Basics of Metaprogramming in RubyBasics of Metaprogramming in Ruby
Basics of Metaprogramming in Ruby
Digital Natives
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
Nate Abele
 
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
swentel
 
Bioinformatica 27-10-2011-p4-files
Bioinformatica 27-10-2011-p4-filesBioinformatica 27-10-2011-p4-files
Bioinformatica 27-10-2011-p4-files
Prof. Wim Van Criekinge
 
Php object orientation and classes
Php object orientation and classesPhp object orientation and classes
Php object orientation and classesKumar
 
Apache Hacks
Apache HacksApache Hacks
Apache Hacks
Beth Skwarecki
 

Similar to Introduction to Twig (20)

Objects, Testing, and Responsibility
Objects, Testing, and ResponsibilityObjects, Testing, and Responsibility
Objects, Testing, and Responsibility
 
Wordpress Plugin Development Practices
Wordpress Plugin Development PracticesWordpress Plugin Development Practices
Wordpress Plugin Development Practices
 
Empezando con Twig
Empezando con TwigEmpezando con Twig
Empezando con Twig
 
Symfony2 and MongoDB - MidwestPHP 2013
Symfony2 and MongoDB - MidwestPHP 2013   Symfony2 and MongoDB - MidwestPHP 2013
Symfony2 and MongoDB - MidwestPHP 2013
 
Effective PHP. Part 3
Effective PHP. Part 3Effective PHP. Part 3
Effective PHP. Part 3
 
Elasticsearch in 15 minutes
Elasticsearch in 15 minutesElasticsearch in 15 minutes
Elasticsearch in 15 minutes
 
Twig Brief, Tips&Tricks
Twig Brief, Tips&TricksTwig Brief, Tips&Tricks
Twig Brief, Tips&Tricks
 
Building maintainable javascript applications
Building maintainable javascript applicationsBuilding maintainable javascript applications
Building maintainable javascript applications
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Questions On The Code And Core Module
Questions On The Code And Core ModuleQuestions On The Code And Core Module
Questions On The Code And Core Module
 
Doctrine in FLOW3
Doctrine in FLOW3Doctrine in FLOW3
Doctrine in FLOW3
 
If you have a problem, if no one else can help... and if you can find them, m...
If you have a problem, if no one else can help... and if you can find them, m...If you have a problem, if no one else can help... and if you can find them, m...
If you have a problem, if no one else can help... and if you can find them, m...
 
Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching logging
 
Basics of Metaprogramming in Ruby
Basics of Metaprogramming in RubyBasics of Metaprogramming in Ruby
Basics of Metaprogramming in Ruby
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
 
Bioinformatica 27-10-2011-p4-files
Bioinformatica 27-10-2011-p4-filesBioinformatica 27-10-2011-p4-files
Bioinformatica 27-10-2011-p4-files
 
Php object orientation and classes
Php object orientation and classesPhp object orientation and classes
Php object orientation and classes
 
Apache Hacks
Apache HacksApache Hacks
Apache Hacks
 

More from markstory

Dependency injection in CakePHP
Dependency injection in CakePHPDependency injection in CakePHP
Dependency injection in CakePHP
markstory
 
Safer, More Helpful CakePHP
Safer, More Helpful CakePHPSafer, More Helpful CakePHP
Safer, More Helpful CakePHP
markstory
 
CakePHP - The Road Ahead
CakePHP - The Road AheadCakePHP - The Road Ahead
CakePHP - The Road Ahead
markstory
 
Future of HTTP in CakePHP
Future of HTTP in CakePHPFuture of HTTP in CakePHP
Future of HTTP in CakePHP
markstory
 
CakePHP mistakes made 2015
CakePHP mistakes made 2015CakePHP mistakes made 2015
CakePHP mistakes made 2015
markstory
 
New in cakephp3
New in cakephp3New in cakephp3
New in cakephp3
markstory
 
PHP WTF
PHP WTFPHP WTF
PHP WTF
markstory
 
CakePHP 3.0 and beyond
CakePHP 3.0 and beyondCakePHP 3.0 and beyond
CakePHP 3.0 and beyond
markstory
 
CakePHP mistakes made confoo 2015
CakePHP mistakes made confoo 2015CakePHP mistakes made confoo 2015
CakePHP mistakes made confoo 2015
markstory
 
CakePHP mistakes made
CakePHP mistakes madeCakePHP mistakes made
CakePHP mistakes made
markstory
 
Performance and optimization CakeFest 2014
Performance and optimization CakeFest 2014Performance and optimization CakeFest 2014
Performance and optimization CakeFest 2014
markstory
 
Road to CakePHP 3.0
Road to CakePHP 3.0Road to CakePHP 3.0
Road to CakePHP 3.0
markstory
 
Performance and optimization
Performance and optimizationPerformance and optimization
Performance and optimization
markstory
 
OWASP Top 10 2013
OWASP Top 10 2013OWASP Top 10 2013
OWASP Top 10 2013
markstory
 
CakePHP the yum & yuck
CakePHP the yum & yuckCakePHP the yum & yuck
CakePHP the yum & yuck
markstory
 
Owasp top 10
Owasp top 10Owasp top 10
Owasp top 10markstory
 
Simple search with elastic search
Simple search with elastic searchSimple search with elastic search
Simple search with elastic search
markstory
 
Making the most of 2.2
Making the most of 2.2Making the most of 2.2
Making the most of 2.2
markstory
 
Intro to continuous integration
Intro to continuous integration Intro to continuous integration
Intro to continuous integration markstory
 
Evented applications with RabbitMQ and CakePHP
Evented applications with RabbitMQ and CakePHPEvented applications with RabbitMQ and CakePHP
Evented applications with RabbitMQ and CakePHP
markstory
 

More from markstory (20)

Dependency injection in CakePHP
Dependency injection in CakePHPDependency injection in CakePHP
Dependency injection in CakePHP
 
Safer, More Helpful CakePHP
Safer, More Helpful CakePHPSafer, More Helpful CakePHP
Safer, More Helpful CakePHP
 
CakePHP - The Road Ahead
CakePHP - The Road AheadCakePHP - The Road Ahead
CakePHP - The Road Ahead
 
Future of HTTP in CakePHP
Future of HTTP in CakePHPFuture of HTTP in CakePHP
Future of HTTP in CakePHP
 
CakePHP mistakes made 2015
CakePHP mistakes made 2015CakePHP mistakes made 2015
CakePHP mistakes made 2015
 
New in cakephp3
New in cakephp3New in cakephp3
New in cakephp3
 
PHP WTF
PHP WTFPHP WTF
PHP WTF
 
CakePHP 3.0 and beyond
CakePHP 3.0 and beyondCakePHP 3.0 and beyond
CakePHP 3.0 and beyond
 
CakePHP mistakes made confoo 2015
CakePHP mistakes made confoo 2015CakePHP mistakes made confoo 2015
CakePHP mistakes made confoo 2015
 
CakePHP mistakes made
CakePHP mistakes madeCakePHP mistakes made
CakePHP mistakes made
 
Performance and optimization CakeFest 2014
Performance and optimization CakeFest 2014Performance and optimization CakeFest 2014
Performance and optimization CakeFest 2014
 
Road to CakePHP 3.0
Road to CakePHP 3.0Road to CakePHP 3.0
Road to CakePHP 3.0
 
Performance and optimization
Performance and optimizationPerformance and optimization
Performance and optimization
 
OWASP Top 10 2013
OWASP Top 10 2013OWASP Top 10 2013
OWASP Top 10 2013
 
CakePHP the yum & yuck
CakePHP the yum & yuckCakePHP the yum & yuck
CakePHP the yum & yuck
 
Owasp top 10
Owasp top 10Owasp top 10
Owasp top 10
 
Simple search with elastic search
Simple search with elastic searchSimple search with elastic search
Simple search with elastic search
 
Making the most of 2.2
Making the most of 2.2Making the most of 2.2
Making the most of 2.2
 
Intro to continuous integration
Intro to continuous integration Intro to continuous integration
Intro to continuous integration
 
Evented applications with RabbitMQ and CakePHP
Evented applications with RabbitMQ and CakePHPEvented applications with RabbitMQ and CakePHP
Evented applications with RabbitMQ and CakePHP
 

Introduction to Twig

  • 2. ABOUT ME Team lead at FreshBooks Lead Developer of CakePHP Contributor to Twig Saturday, 3 November, 12
  • 3. WHAT IS IT Templating language for PHP. Uses syntax and ideas from jinja2. Flexible and extensible at every layer. Saturday, 3 November, 12
  • 4. BUT PHP IS A TEMPLATING LANGUAGE DUMMY Saturday, 3 November, 12
  • 5. PHP SUCKS FOR TEMPLATING // In Plain PHP <?php echo $var; ?> (XSS you lose) <?php echo htmlspecialchars($var, ENT_QUOTES, ‘UTF-8’); ?> <?php echo h($var); ?> (sugar for htmlentities) // In Twig - autoescaping enabled {{ var }} Saturday, 3 November, 12
  • 6. BENEFITS OF TWIG Terse syntax, and sugar. Automatic HTML escaping. Sandbox mode, which enables user editable templates. Ability to create custom DSL’s using application tags, operators and functions. Saturday, 3 November, 12
  • 7. PLAIN PHP VS TWIG Saturday, 3 November, 12
  • 8. CONDITIONALS // In Plain PHP <?php if (!empty($var): ?> ... <?php endif; ?> // In Twig {% if var %} ... {% endif %} Saturday, 3 November, 12
  • 9. LOOPS <?php if (!empty($var): foreach ((array)$var as $i => $v): printf( ‘%s : %s’, htmlspecialchars($i, ENT_QUOTES, ‘UTF-8’), htmlspecialchars($v, ENT_QUOTES, ‘UTF-8’)); endforeach; else: echo ‘No things’; endif; Saturday, 3 November, 12
  • 10. LOOPS {% for i, v in var %} {{ i }} : {{ v }} {% else %} No things {% endfor %} Saturday, 3 November, 12
  • 11. LOOPS {% for user in users if user.active %} {{ user.name }} : {{ user.email }} {% else %} No active users {% endfor %} Saturday, 3 November, 12
  • 12. BUT WAIT THERE IS MORE Saturday, 3 November, 12
  • 13. AWESOME++ Macros. Blocks & extending templates. Saturday, 3 November, 12
  • 14. MACROS {% macro username(user) %} <a href=”{{ url({ ‘controller’: ‘users’, ‘action’: ‘view’, user.username) }}”> <span class=”user-first-name”> {{ user.first_name }} </span> <span> class=”user-last-name”> {{ user.last_name }} </span> </a> {% endmacro %} Saturday, 3 November, 12
  • 15. IMPORTING MACROS // import all the macros {% import ‘/import/formatting.twig’ as formatting %} {{ formatting.username(user) }} // import one macro {% from ‘/import/formatting.twig’ import username %} {{ username(user) }} // import one & alias it. {% from ‘/import/formatting.twig’ import username as un %} {{ un(user) }} Saturday, 3 November, 12
  • 16. INHERITANCE & BLOCKS Extending views & blocks work hand in hand. Blocks are like slots or holes in a template, that the child can fill. Blocks can be used out of order, which is pretty sweet. Blocks can be imported from other templates, similar to traits. Saturday, 3 November, 12
  • 17. INHERITANCE {# layout/base.twig #} Company X - Official Email template {% block content ‘Super important’ %} Copyright 2012 Saturday, 3 November, 12
  • 18. INHERITANCE {# email/winner.twig #} {% extend ‘/layout/base.twig’ %} {% block content %} To whom it may concern, You win! {% endblock %} Saturday, 3 November, 12
  • 19. INHERITANCE {# email/winner.twig #} {% extend ‘/layout/base.twig’ %} {% block content %} To whom it may concern, {{ parent() }} You win! {% endblock %} Saturday, 3 November, 12
  • 20. INHERITANCE TIPS Don’t use {% block %} inside a loop. It doesn’t do what you want. You can use {{ block(name) }} to dynamically call blocks. Saturday, 3 November, 12
  • 21. EXTENDING TWIG TWIG EXTENSIONS Saturday, 3 November, 12
  • 22. EXTENDING TWIG Twig can be extended in several ways. Filters, Functions, Globals, Tests, Operators, TokenParsers, NodeVisitors. You should use extensions to package up your enhancements. Saturday, 3 November, 12
  • 24. LOADING EXTENSIONS $loader = new Twig_Loader_FileSystem(APP . ‘/templates’); $twig = new Twig_Environment($loader, $options); $twig->addExtension(new App_Extension_Url()); Saturday, 3 November, 12
  • 25. ENVIRONMENT FACTORY class AppTwig { static function loadTemplate($template, $options = array()) { $loader = new Twig_Loader_FileSystem(APP . ‘/templates’); $twig = new Twig_Environment($loader, $options); $twig->addExtension(new App_Extension_Url()); // Load more extensions return $twig->loadTemplate($template); } } $template = AppTwig::loadTemplate(‘/users/profile.twig’); Saturday, 3 November, 12
  • 26. EXTENSION EXAMPLE <?php class App_Extension_Url extends Twig_Extension { public function getName() { return ‘app.url’; } public function getFilters() { return array( ‘name’ => new Twig_Filter_Method($this, ‘formatName’), ); } } Saturday, 3 November, 12
  • 27. GLOBALS Can be used to expose application or framework objects. Great for migrating an older codebase to use Twig. E.g {{ html.link(...) }} Saturday, 3 November, 12
  • 28. FUNCTIONS Global functions added to a template context. Great for providing shortcuts to application features, like url generation or built-in PHP functions. Example {{ form_input(model, ‘name’) }} Saturday, 3 November, 12
  • 29. FILTERS Filters are intended for simple formatting functions. The filtered variable is the first argument to the filter function. Filters can have additional arguments as well. Example: {{ invoice.amount|currency(‘CAD’) }} Saturday, 3 November, 12
  • 30. TESTS Allow you to implement custom conditional logic. In an expressive manner with domain objects. Value being compared is supplied as the first argument. Other arguments follow. {% if user is paying %} {% if number is divisibleby(3) %} Saturday, 3 November, 12
  • 31. NODE VISITORS Allows you to visit each node in the Abstract syntax tree. Applied before template is compiled. Commonly used for optimizing the AST, or applying transformations to, or reading data from nodes in the tree. Saturday, 3 November, 12
  • 32. CUSTOM TAGS Saturday, 3 November, 12
  • 33. TWIG INTERNALS ENVIRONMENT LOADER Saturday, 3 November, 12
  • 34. TWIG INTERNALS ENVIRONMENT LEXER LOADER Saturday, 3 November, 12
  • 35. TWIG INTERNALS ENVIRONMENT LEXER LOADER TOKENS Saturday, 3 November, 12
  • 36. TWIG INTERNALS ENVIRONMENT LEXER PARSER LOADER TOKENS Saturday, 3 November, 12
  • 37. TWIG INTERNALS ENVIRONMENT LEXER PARSER LOADER TOKENS NODES Saturday, 3 November, 12
  • 38. TWIG INTERNALS ENVIRONMENT LEXER PARSER COMPILER LOADER TOKENS NODES Saturday, 3 November, 12
  • 39. TWIG INTERNALS ENVIRONMENT LEXER PARSER COMPILER LOADER TOKENS NODES PHP CODE Saturday, 3 November, 12
  • 40. TOKEN PARSERS Used to implement custom tags or DSL features. The most complex feature to add. Each tag is composed of two parts: TokenParser - parses the tag and validates its syntax. Node - Added to the AST and compiles the PHP code used in templates. Saturday, 3 November, 12
  • 41. TAG EXAMPLE {% debug %} {% debug my_var %} {% debug 2 > 1 %} Saturday, 3 November, 12
  • 42. TOKEN PARSER class App_TokenParser_Debug extends Twig_TokenParser { public function parse(Twig_Token $token) { $line = $token->getLine(); $expr = null; if (!$this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE)) { $expr = $this->parser->getExpressionParser->parseExpression(); } $this->parse->getStream()->expect(Twig_Token::BLOCK_END_TYPE); return new App_Node_Debug($expr, $line, $this->getTag()); } } Saturday, 3 November, 12
  • 43. NODE COMPILER class App_Node_Debug extends Twig_Node { public function __construct(Twig_Node_Expression $ex, $line, $tag) { parent::__construct(array(‘expr’ => $ex), $line, $tag); } public function compile(Twig_Compiler $compiler) { $compiler->write(‘if ($this->env->isDebug()) {‘); if ($this->getNode(‘expr’) === null) { // Print all vars. } else { $compiler->write(‘var_dump(‘) ->subcompile($this->getNode(‘expr’)) ->raw(‘);’); } $compiler->write(‘}’); } } Saturday, 3 November, 12
  • 44. OPERATORS Allow you to add additional boolean operators. I’ve never used this feature. Saturday, 3 November, 12
  • 46. TWIG IN PRODUCTION FreshBooks (the app, not the website). 520+ templates. Twig templates are used for almost all HTML & E-mail content. Saturday, 3 November, 12
  • 47. TEMPLATE COMPILATION TWIG Saturday, 3 November, 12
  • 48. TEMPLATE COMPILATION TWIG PHP Saturday, 3 November, 12
  • 49. TEMPLATE COMPILATION TWIG PHP HTML Saturday, 3 November, 12
  • 50. TEMPLATE COMPILATION TWIG PHP HTML Saved to disk Saturday, 3 November, 12
  • 51. TEMPLATE COMPILATION PHP HTML Saved to disk Saturday, 3 November, 12
  • 52. HOW WE DEPLOY Saturday, 3 November, 12
  • 53. HOW WE DEPLOY COPY FILES Saturday, 3 November, 12
  • 54. HOW WE DEPLOY COPY COMPILE FILES / BUILD Saturday, 3 November, 12
  • 55. HOW WE DEPLOY COPY COMPILE SYMLINK FILES / BUILD Saturday, 3 November, 12
  • 56. PRECOMPILE SCRIPT $directory = new RecursiveDirectoryIterator($argv[0]); $recurser = new RecursiveIteratorIterator($directory); $matcher = new RegexIterator( $recurser, '/.*?.twig$/', RegexIterator::GET_MATCH); echo "Compiling Templatesn"; $i = 0; foreach ($matcher as $file) { $filename = str_replace($argv[1], '', $file[0]); AppTwig::loadTemplate('/' . $filename); echo '.'; $i++; } echo "nTemplates compiledn"; exit(0); Saturday, 3 November, 12
  • 57. TWIG C EXTENSION You can also install ext/twig. This pushes the most frequently used method Twig_Template::getAttribute() into C which increases performance considerably. The C extension is in the Twig repository. Saturday, 3 November, 12
  • 59. THANKS @MARK_STORY HTTP://MARK-STORY.COM Saturday, 3 November, 12