Twig内部构件¶
Twig是非常可扩展的,你可以破解它。请记住,您可能应该在破解核心之前尝试创建一个扩展,因为大多数特性和增强都可以通过扩展来处理。想了解这一章对谁也有用。
树枝是怎么工作的?¶
Twig模板的渲染可概括为四个关键步骤:
- Load 模板:如果模板已经编译,加载它并转到 评价 步骤,否则:
- 首先, 莱克塞 将模板源代码标记成小块,以便于处理;
- 然后, 语法分析器 将令牌流转换为有意义的节点树(抽象语法树);
- 最后, 编译器 将AST转换为PHP代码。
- 评估 模板:它意味着调用
display()
方法,并将其传递给上下文。
雷克瑟¶
lexer将模板源代码标记为令牌流(每个令牌都是 \Twig\Token
,流是 \Twig\TokenStream
). 默认的lexer可以识别13种不同的令牌类型:
\Twig\Token::BLOCK_START_TYPE
,\Twig\Token::BLOCK_END_TYPE
:块的分隔符 ({{% %}}
)\Twig\Token::VAR_START_TYPE
,\Twig\Token::VAR_END_TYPE
:变量的分隔符 ({{{{ }}}}
)\Twig\Token::TEXT_TYPE
:表达式外的文本;\Twig\Token::NAME_TYPE
:表达式中的名称;\Twig\Token::NUMBER_TYPE
:表达式中的数字;\Twig\Token::STRING_TYPE
:表达式中的字符串;\Twig\Token::OPERATOR_TYPE
:操作员;\Twig\Token::PUNCTUATION_TYPE
:标点符号;\Twig\Token::INTERPOLATION_START_TYPE
,\Twig\Token::INTERPOLATION_END_TYPE
:字符串插值的分隔符;\Twig\Token::EOF_TYPE
:模板结束。
您可以通过调用 tokenize()
环境方法:
$stream = $twig->tokenize(new \Twig\Source($source, $identifier));
因为溪流有一个 __toString()
方法,您可以通过回显对象来获得它的文本表示形式:
echo $stream."\n";
下面是 Hello {{{{ name }}}}
模板:
1 2 3 4 5 | TEXT_TYPE(Hello )
VAR_START_TYPE()
NAME_TYPE(name)
VAR_END_TYPE()
EOF_TYPE()
|
注解
默认的lexer (\Twig\Lexer
)可以通过调用 setLexer()
方法:
$twig->setLexer($lexer);
语法分析器¶
解析器将令牌流转换为AST(抽象语法树)或节点树(的实例 \Twig\Node\ModuleNode
). 核心扩展定义了如下基本节点: for
, if
, ... 以及表达式节点。
您可以通过调用 parse()
环境方法:
$nodes = $twig->parse($stream);
回显node对象可以很好地表示树:
echo $nodes."\n";
下面是 Hello {{{{ name }}}}
模板:
1 2 3 4 5 6 | \Twig\Node\ModuleNode(
\Twig\Node\TextNode(Hello )
\Twig\Node\PrintNode(
\Twig\Node\Expression\NameExpression(name)
)
)
|
注解
默认解析器 (\Twig\TokenParser\AbstractTokenParser
)可以通过调用 setParser()
方法:
$twig->setParser($parser);
编译器¶
最后一步由编译器完成。它以一个节点树作为输入,并生成可在运行时执行模板的PHP代码。
您可以使用 compile()
环境方法:
$php = $twig->compile($nodes);
生成的模板 Hello {{{{ name }}}}
模板如下所示(实际输出可能因使用的Twig版本而异):
/* Hello {{ name }} */
class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Template
{
protected function doDisplay(array $context, array $blocks = [])
{
// line 1
echo "Hello ";
echo twig_escape_filter($this->env, (isset($context["name"]) ? $context["name"] : null), "html", null, true);
}
// some more code
}
注解
默认编译器 (\Twig\Compiler
)可以通过调用 setCompiler()
方法:
$twig->setCompiler($compiler);