introduction to twig
TRANSCRIPT
![Page 1: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/1.jpg)
TWIG
Saturday, 3 November, 12
![Page 2: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/2.jpg)
ABOUT ME
Team lead at FreshBooks
Lead Developer of CakePHP
Contributor to Twig
Saturday, 3 November, 12
![Page 3: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/3.jpg)
WHAT IS IT
Templating language for PHP.
Uses syntax and ideas from jinja2.
Flexible and extensible at every layer.
Saturday, 3 November, 12
![Page 4: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/4.jpg)
BUT PHP IS A TEMPLATING
LANGUAGE DUMMY
Saturday, 3 November, 12
![Page 5: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/5.jpg)
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
![Page 6: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/6.jpg)
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
![Page 7: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/7.jpg)
PLAIN PHP VS TWIG
Saturday, 3 November, 12
![Page 8: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/8.jpg)
CONDITIONALS
// In Plain PHP<?php if (!empty($var): ?>...<?php endif; ?>
// In Twig{% if var %}...{% endif %}
Saturday, 3 November, 12
![Page 9: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/9.jpg)
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
![Page 10: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/10.jpg)
LOOPS
{% for i, v in var %}{{ i }} : {{ v }}{% else %}No things{% endfor %}
Saturday, 3 November, 12
![Page 11: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/11.jpg)
LOOPS
{% for user in users if user.active %}{{ user.name }} : {{ user.email }}{% else %}No active users{% endfor %}
Saturday, 3 November, 12
![Page 12: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/12.jpg)
BUT WAIT THERE IS MORE
Saturday, 3 November, 12
![Page 13: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/13.jpg)
AWESOME++
Macros.
Blocks & extending templates.
Saturday, 3 November, 12
![Page 14: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/14.jpg)
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
![Page 15: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/15.jpg)
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
![Page 16: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/16.jpg)
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
![Page 17: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/17.jpg)
INHERITANCE
{# layout/base.twig #}
Company X - Official Email template
{% block content ‘Super important’ %}
Copyright 2012
Saturday, 3 November, 12
![Page 18: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/18.jpg)
INHERITANCE
{# email/winner.twig #}{% extend ‘/layout/base.twig’ %}
{% block content %}To whom it may concern,
You win!{% endblock %}
Saturday, 3 November, 12
![Page 19: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/19.jpg)
INHERITANCE
{# email/winner.twig #}{% extend ‘/layout/base.twig’ %}
{% block content %}To whom it may concern,
{{ parent() }} You win!
{% endblock %}
Saturday, 3 November, 12
![Page 20: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/20.jpg)
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
![Page 21: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/21.jpg)
EXTENDING TWIGTWIG EXTENSIONS
Saturday, 3 November, 12
![Page 22: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/22.jpg)
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
![Page 23: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/23.jpg)
TWIG EXTENSIONS
Saturday, 3 November, 12
![Page 24: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/24.jpg)
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
![Page 25: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/25.jpg)
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 extensionsreturn $twig->loadTemplate($template);
}}
$template = AppTwig::loadTemplate(‘/users/profile.twig’);
Saturday, 3 November, 12
![Page 26: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/26.jpg)
EXTENSION EXAMPLE
<?phpclass 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
![Page 27: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/27.jpg)
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
![Page 28: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/28.jpg)
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
![Page 29: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/29.jpg)
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
![Page 30: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/30.jpg)
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
![Page 31: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/31.jpg)
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
![Page 32: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/32.jpg)
CUSTOM TAGS
Saturday, 3 November, 12
![Page 33: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/33.jpg)
TWIG INTERNALS
LOADER
ENVIRONMENT
Saturday, 3 November, 12
![Page 34: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/34.jpg)
TWIG INTERNALS
LOADER
LEXERENVIRONMENT
Saturday, 3 November, 12
![Page 35: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/35.jpg)
TWIG INTERNALS
LOADER
LEXERENVIRONMENT
TOKENS
Saturday, 3 November, 12
![Page 36: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/36.jpg)
TWIG INTERNALS
LOADER
LEXERENVIRONMENT
TOKENS
PARSER
Saturday, 3 November, 12
![Page 37: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/37.jpg)
TWIG INTERNALS
LOADER
LEXERENVIRONMENT
TOKENS
PARSER
NODES
Saturday, 3 November, 12
![Page 38: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/38.jpg)
TWIG INTERNALS
LOADER
LEXERENVIRONMENT
TOKENS
PARSER COMPILER
NODES
Saturday, 3 November, 12
![Page 39: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/39.jpg)
TWIG INTERNALS
LOADER
LEXERENVIRONMENT
TOKENS
PARSER COMPILER
NODES
PHP CODE
Saturday, 3 November, 12
![Page 40: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/40.jpg)
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
![Page 41: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/41.jpg)
TAG EXAMPLE
{% debug %}
{% debug my_var %}
{% debug 2 > 1 %}
Saturday, 3 November, 12
![Page 42: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/42.jpg)
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
![Page 43: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/43.jpg)
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
![Page 44: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/44.jpg)
OPERATORS
Allow you to add additional boolean operators.
I’ve never used this feature.
Saturday, 3 November, 12
![Page 45: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/45.jpg)
DEPLOYING TWIG
Saturday, 3 November, 12
![Page 46: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/46.jpg)
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
![Page 47: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/47.jpg)
TEMPLATE COMPILATION
TWIG
Saturday, 3 November, 12
![Page 48: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/48.jpg)
TEMPLATE COMPILATION
TWIG PHP
Saturday, 3 November, 12
![Page 49: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/49.jpg)
TEMPLATE COMPILATION
TWIG PHP HTML
Saturday, 3 November, 12
![Page 50: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/50.jpg)
TEMPLATE COMPILATION
TWIG PHP HTML
Saved to disk
Saturday, 3 November, 12
![Page 51: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/51.jpg)
TEMPLATE COMPILATION
PHP HTML
Saved to disk
Saturday, 3 November, 12
![Page 52: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/52.jpg)
HOW WE DEPLOY
Saturday, 3 November, 12
![Page 53: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/53.jpg)
HOW WE DEPLOY
COPY FILES
Saturday, 3 November, 12
![Page 54: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/54.jpg)
HOW WE DEPLOY
COPY FILES
COMPILE / BUILD
Saturday, 3 November, 12
![Page 55: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/55.jpg)
HOW WE DEPLOY
COPY FILES
COMPILE / BUILD SYMLINK
Saturday, 3 November, 12
![Page 56: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/56.jpg)
PRECOMPILE SCRIPT
$directory = new RecursiveDirectoryIterator($argv[0]);$recurser = new RecursiveIteratorIterator($directory);$matcher = new RegexIterator(
$recurser,'/.*?\.twig$/',RegexIterator::GET_MATCH);
echo "Compiling Templates\n";
$i = 0;foreach ($matcher as $file) {
$filename = str_replace($argv[1], '', $file[0]);AppTwig::loadTemplate('/' . $filename);echo '.';$i++;
}echo "\nTemplates compiled\n";exit(0);
Saturday, 3 November, 12
![Page 57: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/57.jpg)
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
![Page 58: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/58.jpg)
QUESTIONS?
Saturday, 3 November, 12
![Page 59: Introduction to Twig](https://reader034.vdocuments.us/reader034/viewer/2022042521/554fbad2b4c9053d018b471f/html5/thumbnails/59.jpg)
THANKS@MARK_STORY
HTTP://MARK-STORY.COM
Saturday, 3 November, 12