/usr/share/doc/php-twig/manual/internals.html is in php-twig-doc 2.4.6-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Twig Internals — php-twig-doc 2.4.6 documentation</title>
<link rel="stylesheet" href="_static/classic.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '2.4.6',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Recipes" href="recipes.html" />
<link rel="prev" title="Extending Twig" href="advanced.html" />
</head>
<body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="recipes.html" title="Recipes"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="advanced.html" title="Extending Twig"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">php-twig-doc 2.4.6 documentation</a> »</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="twig-internals">
<h1>Twig Internals<a class="headerlink" href="#twig-internals" title="Permalink to this headline">¶</a></h1>
<p>Twig is very extensible and you can easily hack it. Keep in mind that you
should probably try to create an extension before hacking the core, as most
features and enhancements can be handled with extensions. This chapter is also
useful for people who want to understand how Twig works under the hood.</p>
<div class="section" id="how-does-twig-work">
<h2>How does Twig work?<a class="headerlink" href="#how-does-twig-work" title="Permalink to this headline">¶</a></h2>
<p>The rendering of a Twig template can be summarized into four key steps:</p>
<ul class="simple">
<li><strong>Load</strong> the template: If the template is already compiled, load it and go
to the <em>evaluation</em> step, otherwise:<ul>
<li>First, the <strong>lexer</strong> tokenizes the template source code into small pieces
for easier processing;</li>
<li>Then, the <strong>parser</strong> converts the token stream into a meaningful tree
of nodes (the Abstract Syntax Tree);</li>
<li>Eventually, the <em>compiler</em> transforms the AST into PHP code.</li>
</ul>
</li>
<li><strong>Evaluate</strong> the template: It basically means calling the <code class="docutils literal"><span class="pre">display()</span></code>
method of the compiled template and passing it the context.</li>
</ul>
</div>
<div class="section" id="the-lexer">
<h2>The Lexer<a class="headerlink" href="#the-lexer" title="Permalink to this headline">¶</a></h2>
<p>The lexer tokenizes a template source code into a token stream (each token is
an instance of <code class="docutils literal"><span class="pre">Twig_Token</span></code>, and the stream is an instance of
<code class="docutils literal"><span class="pre">Twig_TokenStream</span></code>). The default lexer recognizes 13 different token types:</p>
<ul class="simple">
<li><code class="docutils literal"><span class="pre">Twig_Token::BLOCK_START_TYPE</span></code>, <code class="docutils literal"><span class="pre">Twig_Token::BLOCK_END_TYPE</span></code>: Delimiters for blocks (<code class="docutils literal"><span class="pre">{%</span> <span class="pre">%}</span></code>)</li>
<li><code class="docutils literal"><span class="pre">Twig_Token::VAR_START_TYPE</span></code>, <code class="docutils literal"><span class="pre">Twig_Token::VAR_END_TYPE</span></code>: Delimiters for variables (<code class="docutils literal"><span class="pre">{{</span> <span class="pre">}}</span></code>)</li>
<li><code class="docutils literal"><span class="pre">Twig_Token::TEXT_TYPE</span></code>: A text outside an expression;</li>
<li><code class="docutils literal"><span class="pre">Twig_Token::NAME_TYPE</span></code>: A name in an expression;</li>
<li><code class="docutils literal"><span class="pre">Twig_Token::NUMBER_TYPE</span></code>: A number in an expression;</li>
<li><code class="docutils literal"><span class="pre">Twig_Token::STRING_TYPE</span></code>: A string in an expression;</li>
<li><code class="docutils literal"><span class="pre">Twig_Token::OPERATOR_TYPE</span></code>: An operator;</li>
<li><code class="docutils literal"><span class="pre">Twig_Token::PUNCTUATION_TYPE</span></code>: A punctuation sign;</li>
<li><code class="docutils literal"><span class="pre">Twig_Token::INTERPOLATION_START_TYPE</span></code>, <code class="docutils literal"><span class="pre">Twig_Token::INTERPOLATION_END_TYPE</span></code>: Delimiters for string interpolation;</li>
<li><code class="docutils literal"><span class="pre">Twig_Token::EOF_TYPE</span></code>: Ends of template.</li>
</ul>
<p>You can manually convert a source code into a token stream by calling the
<code class="docutils literal"><span class="pre">tokenize()</span></code> method of an environment:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span>$stream = $twig->tokenize(new Twig_Source($source, $identifier));
</pre></div>
</div>
<p>As the stream has a <code class="docutils literal"><span class="pre">__toString()</span></code> method, you can have a textual
representation of it by echoing the object:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span>echo $stream."\n";
</pre></div>
</div>
<p>Here is the output for the <code class="docutils literal"><span class="pre">Hello</span> <span class="pre">{{</span> <span class="pre">name</span> <span class="pre">}}</span></code> template:</p>
<div class="highlight-text"><div class="highlight"><pre><span></span>TEXT_TYPE(Hello )
VAR_START_TYPE()
NAME_TYPE(name)
VAR_END_TYPE()
EOF_TYPE()
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>The default lexer (<code class="docutils literal"><span class="pre">Twig_Lexer</span></code>) can be changed by calling
the <code class="docutils literal"><span class="pre">setLexer()</span></code> method:</p>
<div class="last highlight-default"><div class="highlight"><pre><span></span>$twig->setLexer($lexer);
</pre></div>
</div>
</div>
</div>
<div class="section" id="the-parser">
<h2>The Parser<a class="headerlink" href="#the-parser" title="Permalink to this headline">¶</a></h2>
<p>The parser converts the token stream into an AST (Abstract Syntax Tree), or a
node tree (an instance of <code class="docutils literal"><span class="pre">Twig_Node_Module</span></code>). The core extension defines
the basic nodes like: <code class="docutils literal"><span class="pre">for</span></code>, <code class="docutils literal"><span class="pre">if</span></code>, … and the expression nodes.</p>
<p>You can manually convert a token stream into a node tree by calling the
<code class="docutils literal"><span class="pre">parse()</span></code> method of an environment:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span>$nodes = $twig->parse($stream);
</pre></div>
</div>
<p>Echoing the node object gives you a nice representation of the tree:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span>echo $nodes."\n";
</pre></div>
</div>
<p>Here is the output for the <code class="docutils literal"><span class="pre">Hello</span> <span class="pre">{{</span> <span class="pre">name</span> <span class="pre">}}</span></code> template:</p>
<div class="highlight-text"><div class="highlight"><pre><span></span>Twig_Node_Module(
Twig_Node_Text(Hello )
Twig_Node_Print(
Twig_Node_Expression_Name(name)
)
)
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>The default parser (<code class="docutils literal"><span class="pre">Twig_TokenParser</span></code>) can be changed by calling the
<code class="docutils literal"><span class="pre">setParser()</span></code> method:</p>
<div class="last highlight-default"><div class="highlight"><pre><span></span>$twig->setParser($parser);
</pre></div>
</div>
</div>
</div>
<div class="section" id="the-compiler">
<h2>The Compiler<a class="headerlink" href="#the-compiler" title="Permalink to this headline">¶</a></h2>
<p>The last step is done by the compiler. It takes a node tree as an input and
generates PHP code usable for runtime execution of the template.</p>
<p>You can manually compile a node tree to PHP code with the <code class="docutils literal"><span class="pre">compile()</span></code> method
of an environment:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span>$php = $twig->compile($nodes);
</pre></div>
</div>
<p>The generated template for a <code class="docutils literal"><span class="pre">Hello</span> <span class="pre">{{</span> <span class="pre">name</span> <span class="pre">}}</span></code> template reads as follows
(the actual output can differ depending on the version of Twig you are
using):</p>
<div class="highlight-default"><div class="highlight"><pre><span></span>/* Hello {{ name }} */
class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Twig_Template
{
protected function doDisplay(array $context, array $blocks = array())
{
// line 1
echo "Hello ";
echo twig_escape_filter($this->env, (isset($context["name"]) ? $context["name"] : null), "html", null, true);
}
// some more code
}
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>The default compiler (<code class="docutils literal"><span class="pre">Twig_Compiler</span></code>) can be changed by calling the
<code class="docutils literal"><span class="pre">setCompiler()</span></code> method:</p>
<div class="last highlight-default"><div class="highlight"><pre><span></span>$twig->setCompiler($compiler);
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Twig Internals</a><ul>
<li><a class="reference internal" href="#how-does-twig-work">How does Twig work?</a></li>
<li><a class="reference internal" href="#the-lexer">The Lexer</a></li>
<li><a class="reference internal" href="#the-parser">The Parser</a></li>
<li><a class="reference internal" href="#the-compiler">The Compiler</a></li>
</ul>
</li>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="advanced.html"
title="previous chapter">Extending Twig</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="recipes.html"
title="next chapter">Recipes</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/internals.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3>Quick search</h3>
<form class="search" action="search.html" method="get">
<div><input type="text" name="q" /></div>
<div><input type="submit" value="Go" /></div>
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="recipes.html" title="Recipes"
>next</a> |</li>
<li class="right" >
<a href="advanced.html" title="Extending Twig"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">php-twig-doc 2.4.6 documentation</a> »</li>
</ul>
</div>
<div class="footer" role="contentinfo">
© Copyright by the Twig Team.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.6.7.
</div>
</body>
</html>
|