diff options
Diffstat (limited to 'vendor/twig/twig/doc/internals.rst')
-rw-r--r-- | vendor/twig/twig/doc/internals.rst | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/vendor/twig/twig/doc/internals.rst b/vendor/twig/twig/doc/internals.rst new file mode 100644 index 00000000..79a3c8d5 --- /dev/null +++ b/vendor/twig/twig/doc/internals.rst | |||
@@ -0,0 +1,140 @@ | |||
1 | Twig Internals | ||
2 | ============== | ||
3 | |||
4 | Twig is very extensible and you can easily hack it. Keep in mind that you | ||
5 | should probably try to create an extension before hacking the core, as most | ||
6 | features and enhancements can be done with extensions. This chapter is also | ||
7 | useful for people who want to understand how Twig works under the hood. | ||
8 | |||
9 | How Twig works? | ||
10 | --------------- | ||
11 | |||
12 | The rendering of a Twig template can be summarized into four key steps: | ||
13 | |||
14 | * **Load** the template: If the template is already compiled, load it and go | ||
15 | to the *evaluation* step, otherwise: | ||
16 | |||
17 | * First, the **lexer** tokenizes the template source code into small pieces | ||
18 | for easier processing; | ||
19 | * Then, the **parser** converts the token stream into a meaningful tree | ||
20 | of nodes (the Abstract Syntax Tree); | ||
21 | * Eventually, the *compiler* transforms the AST into PHP code; | ||
22 | |||
23 | * **Evaluate** the template: It basically means calling the ``display()`` | ||
24 | method of the compiled template and passing it the context. | ||
25 | |||
26 | The Lexer | ||
27 | --------- | ||
28 | |||
29 | The lexer tokenizes a template source code into a token stream (each token is | ||
30 | an instance of ``Twig_Token``, and the stream is an instance of | ||
31 | ``Twig_TokenStream``). The default lexer recognizes 13 different token types: | ||
32 | |||
33 | * ``Twig_Token::BLOCK_START_TYPE``, ``Twig_Token::BLOCK_END_TYPE``: Delimiters for blocks (``{% %}``) | ||
34 | * ``Twig_Token::VAR_START_TYPE``, ``Twig_Token::VAR_END_TYPE``: Delimiters for variables (``{{ }}``) | ||
35 | * ``Twig_Token::TEXT_TYPE``: A text outside an expression; | ||
36 | * ``Twig_Token::NAME_TYPE``: A name in an expression; | ||
37 | * ``Twig_Token::NUMBER_TYPE``: A number in an expression; | ||
38 | * ``Twig_Token::STRING_TYPE``: A string in an expression; | ||
39 | * ``Twig_Token::OPERATOR_TYPE``: An operator; | ||
40 | * ``Twig_Token::PUNCTUATION_TYPE``: A punctuation sign; | ||
41 | * ``Twig_Token::INTERPOLATION_START_TYPE``, ``Twig_Token::INTERPOLATION_END_TYPE`` (as of Twig 1.5): Delimiters for string interpolation; | ||
42 | * ``Twig_Token::EOF_TYPE``: Ends of template. | ||
43 | |||
44 | You can manually convert a source code into a token stream by calling the | ||
45 | ``tokenize()`` of an environment:: | ||
46 | |||
47 | $stream = $twig->tokenize($source, $identifier); | ||
48 | |||
49 | As the stream has a ``__toString()`` method, you can have a textual | ||
50 | representation of it by echoing the object:: | ||
51 | |||
52 | echo $stream."\n"; | ||
53 | |||
54 | Here is the output for the ``Hello {{ name }}`` template: | ||
55 | |||
56 | .. code-block:: text | ||
57 | |||
58 | TEXT_TYPE(Hello ) | ||
59 | VAR_START_TYPE() | ||
60 | NAME_TYPE(name) | ||
61 | VAR_END_TYPE() | ||
62 | EOF_TYPE() | ||
63 | |||
64 | .. note:: | ||
65 | |||
66 | You can change the default lexer use by Twig (``Twig_Lexer``) by calling | ||
67 | the ``setLexer()`` method:: | ||
68 | |||
69 | $twig->setLexer($lexer); | ||
70 | |||
71 | The Parser | ||
72 | ---------- | ||
73 | |||
74 | The parser converts the token stream into an AST (Abstract Syntax Tree), or a | ||
75 | node tree (an instance of ``Twig_Node_Module``). The core extension defines | ||
76 | the basic nodes like: ``for``, ``if``, ... and the expression nodes. | ||
77 | |||
78 | You can manually convert a token stream into a node tree by calling the | ||
79 | ``parse()`` method of an environment:: | ||
80 | |||
81 | $nodes = $twig->parse($stream); | ||
82 | |||
83 | Echoing the node object gives you a nice representation of the tree:: | ||
84 | |||
85 | echo $nodes."\n"; | ||
86 | |||
87 | Here is the output for the ``Hello {{ name }}`` template: | ||
88 | |||
89 | .. code-block:: text | ||
90 | |||
91 | Twig_Node_Module( | ||
92 | Twig_Node_Text(Hello ) | ||
93 | Twig_Node_Print( | ||
94 | Twig_Node_Expression_Name(name) | ||
95 | ) | ||
96 | ) | ||
97 | |||
98 | .. note:: | ||
99 | |||
100 | The default parser (``Twig_TokenParser``) can be also changed by calling the | ||
101 | ``setParser()`` method:: | ||
102 | |||
103 | $twig->setParser($parser); | ||
104 | |||
105 | The Compiler | ||
106 | ------------ | ||
107 | |||
108 | The last step is done by the compiler. It takes a node tree as an input and | ||
109 | generates PHP code usable for runtime execution of the template. | ||
110 | |||
111 | You can call the compiler by hand with the ``compile()`` method of an | ||
112 | environment:: | ||
113 | |||
114 | $php = $twig->compile($nodes); | ||
115 | |||
116 | The ``compile()`` method returns the PHP source code representing the node. | ||
117 | |||
118 | The generated template for a ``Hello {{ name }}`` template reads as follows | ||
119 | (the actual output can differ depending on the version of Twig you are | ||
120 | using):: | ||
121 | |||
122 | /* Hello {{ name }} */ | ||
123 | class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Twig_Template | ||
124 | { | ||
125 | protected function doDisplay(array $context, array $blocks = array()) | ||
126 | { | ||
127 | // line 1 | ||
128 | echo "Hello "; | ||
129 | echo twig_escape_filter($this->env, $this->getContext($context, "name"), "ndex", null, true); | ||
130 | } | ||
131 | |||
132 | // some more code | ||
133 | } | ||
134 | |||
135 | .. note:: | ||
136 | |||
137 | As for the lexer and the parser, the default compiler (``Twig_Compiler``) can | ||
138 | be changed by calling the ``setCompiler()`` method:: | ||
139 | |||
140 | $twig->setCompiler($compiler); | ||