面向开发者的树枝
本章描述的是Twig的API,而不是模板语言。对于那些实现应用程序模板接口的人,而不是那些创建Twig模板的人,它将是最有用的参考。
基础知识
Twig使用一个名为环境(类\树枝\环境
).该类的实例用于存储配置和扩展,并用于加载模板。
大多数应用程序都会创建一个\树枝\环境
对象,并使用它来加载模板。在某些情况下,将多个具有不同配置的环境放在一起可能是有用的。
配置Twig为应用程序加载模板的典型方式大致如下:
1 2 3 4 5 6
require_once“/道路/ /供应商/ autoload.php”;$加载程序=新\树枝\装载机\ FilesystemLoader (“/道路/ /模板”);$嫩枝=新\树枝\环境($加载程序, (“缓存”= >“/道路/ / compilation_cache”]);
中查找模板的加载器将创建一个具有默认配置的模板环境/ /模板/ /路径
目录中。有不同的加载器可用,如果您想从数据库或其他资源加载模板,您也可以编写自己的加载器。
请注意
注意,环境的第二个参数是一个选项数组。的缓存
选项是一个编译缓存目录,Twig在其中缓存已编译的模板,以避免后续请求的解析阶段。它与您可能希望为求值模板添加的缓存有很大不同。对于这种需求,您可以使用任何可用的PHP缓存库。
渲染模板
要从Twig环境加载模板,请调用load ()
方法,该方法返回\树枝\ TemplateWrapper
实例:
1
$模板=$嫩枝->负载(“index . html”);
要使用一些变量呈现模板,请调用呈现()
方法:
1
回声$模板->呈现([“的”= >“变量”,“去”= >“在这里”]);
请注意
的显示()
方法是输出呈现的模板的快捷方式。
你也可以一下子加载和渲染模板:
1
回声$嫩枝->呈现(“index . html”, (“的”= >“变量”,“去”= >“在这里”]);
如果模板定义了块,则可以通过renderBlock ()
电话:
1
回声$模板->renderBlock (“block_name”, (“的”= >“变量”,“去”= >“在这里”]);
环境的选择
当创建一个新的\树枝\环境
实例中,你可以传递一个选项数组作为构造函数的第二个参数:
1
$嫩枝=新\树枝\环境($加载程序, (“调试”= >真正的]);
有以下选项:
调试
布尔当设置为
真正的
时,生成的模板有一个__toString ()
方法,可用于显示生成的节点(默认为假
).字符集
字符串(默认为utf - 8
)模板使用的字符集。
base_template_class
字符串(默认为\树枝\模板
)用于生成模板的基模板类。
缓存
字符串或假
存放已编译模板的绝对路径,或者
假
禁用缓存(这是默认的)。auto_reload
布尔当使用Twig进行开发时,每当源代码发生更改时重新编译模板是非常有用的。的值
auto_reload
选项,它将自动确定基于调试
价值。strict_variables
布尔如果设置为
假
, Twig将无声地忽略无效变量(不存在的变量和或属性/方法),并将它们替换为零
价值。当设置为真正的
, Twig反而抛出异常(默认为假
).autoescape
字符串设置默认的自动转义策略(
的名字
,超文本标记语言
,js
,css
,url
,html_attr
,或者一个PHP回调,它接受模板“filename”并返回要使用的转义策略——回调不能是函数名,以避免与内置的转义策略冲突);设置为假
禁用自动转义。的的名字
转义策略根据模板的文件名扩展名确定模板要使用的转义策略(此策略在运行时不会产生任何开销,因为自动转义是在编译时完成的)。优化
整数一个标志,指示应用哪些优化(默认为
-1
——所有的优化都被启用;设置为0
禁用)。
加载器
加载器负责从文件系统等资源加载模板。
编译缓存
所有模板加载器都可以在文件系统上缓存已编译的模板,以便将来重用。它大大提高了Twig的速度,因为模板只编译一次。
内置的加载器
下面是内置加载器的列表:
\树枝\装载机\ FilesystemLoader
\树枝\装载机\ FilesystemLoader
从文件系统加载模板。这个加载器可以在文件系统的文件夹中找到模板,并且是加载它们的首选方式:
1
$加载程序=新\树枝\装载机\ FilesystemLoader ($templateDir);
它还可以在目录数组中查找模板:
1
$加载程序=新\树枝\装载机\ FilesystemLoader ([$templateDir1,$templateDir2]);
有了这样的配置,Twig将首先在templateDir1美元
如果它们不存在,它会退一步在templateDir2美元
.
方法添加或预先添加路径目录()
而且prependPath ()
方法:
1 2
$加载程序->目录$templateDir3);$加载程序->prependPath ($templateDir4);
文件系统加载器还支持名称空间模板。这允许将模板分组在不同的名称空间下,这些名称空间有自己的模板路径。
当使用setPaths ()
,目录()
,prependPath ()
方法,指定命名空间作为第二个参数(当未指定时,这些方法作用于“主”命名空间):
1
$加载程序->目录$templateDir,“管理”);
命名空间模板可以通过特殊的@namespace_name / template_path
符号:
1
$嫩枝->呈现(“@admin / index . html”[]);
\树枝\装载机\ FilesystemLoader
支持绝对路径和相对路径。使用相对路径是首选的,因为它使缓存键独立于项目根目录(例如,它允许从构建服务器加热缓存,其中目录可能与生产服务器上使用的目录不同):
1
$加载程序=新\树枝\装载机\ FilesystemLoader (“模板”, getcwd()。“/ . .”);
请注意
当没有将根路径作为第二个参数传递时,Twig使用getcwd ()
对于相对路径。
\树枝\装载机\ ArrayLoader
\树枝\装载机\ ArrayLoader
从PHP数组中加载模板。它被传递一个绑定到模板名称的字符串数组:
1 2 3 4 5 6
$加载程序=新\树枝\装载机\ ArrayLoader ([“index . html”= >“你好{{name}}!”]);$嫩枝=新\树枝\环境($加载程序);回声$嫩枝->呈现(“index . html”, (“名字”= >“法”]);
这个加载器对于单元测试非常有用。它还可以用于小型项目,其中将所有模板存储在一个PHP文件中可能是有意义的。
提示
当使用数组
加载器带有缓存机制,你应该知道每当模板内容“改变”时都会生成一个新的缓存键(缓存键是模板的源代码)。如果您不想看到您的缓存增长失控,您需要自己清理旧的缓存文件。
\树枝\装载机\ ChainLoader
\树枝\装载机\ ChainLoader
将模板的加载委托给其他加载器:
1 2 3 4 5 6 7 8 9 10 11
$loader1=新\树枝\装载机\ ArrayLoader ([“base.html”= >'{% block内容%}{% endblock %}']);$loader2=新\树枝\装载机\ ArrayLoader ([“index . html”= >'{%扩展"base.html" %}{% block内容%}Hello {{name}}{% endblock %}',“base.html”= >“永远不会载入”]);$加载程序=新\树枝\装载机\ ChainLoader ([$loader1,$loader2]);$嫩枝=新\树枝\环境($加载程序);
在寻找模板时,Twig依次尝试每个加载器,并在找到模板后立即返回。当呈现index . html
从上面的例子模板,Twig将加载它loader2美元
但是,base.html
模板将从loader1美元
.
请注意
方法添加加载器addLoader ()
方法。
创建自己的Loader
所有加载器都实现\树枝\装载机\ LoaderInterface
:
12 34 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
接口\嫩枝\加载程序\LoaderInterface{/** *返回给定模板逻辑名的源上下文。* *@paramstring $name模板逻辑名* *@return\树枝\来源* *@throws当$name没有找到时\Twig\Error\LoaderError公共函数getSourceContext($的名字);/** *获取要用于给定模板名称的缓存的缓存键。* *@paramstring $name要加载的模板名称* *@returnstring缓存键* *@throws当$name没有找到时\Twig\Error\LoaderError公共函数getCacheKey($的名字);/** *如果模板仍然是新的,则返回true。* *@param* . string $name模板名称@paramtimestamp $time缓存的模板最后一次修改时间* *@return如果模板是新的,Bool为true,否则为false@throws当$name没有找到时\Twig\Error\LoaderError公共函数isFresh($的名字,$时间);/** *检查我们是否有一个模板的源代码,给出它的名字。* *@param用于检查是否可以加载* *的模板名称@return是否由该加载器处理模板源代码*/公共函数存在($的名字);}
的isFresh ()
方法必须返回真正的
如果当前缓存的模板仍然是新鲜的,给定最后的修改时间,或者假
否则。
的getSourceContext ()
方法的实例\树枝\源
.
使用扩展
Twig扩展是向Twig添加新功能的包。方法注册扩展addExtension ()
方法:
1
$嫩枝->addExtension (新\ \树枝\扩展SandboxExtension ());
Twig附带以下扩展:
- TwigExtensionCoreExtension:定义了Twig的所有核心特性。
- TwigExtensionDebugExtension:定义
转储
函数帮助调试模板变量。 - TwigExtensionEscaperExtension:添加自动输出转义和转义/不转义代码块的可能性。
- TwigExtensionSandboxExtension:为默认的Twig环境添加沙盒模式,使其安全评估不受信任的代码。
- TwigExtensionProfilerExtension:启用内置的Twig分析器。
- TwigExtensionOptimizerExtension:编译前优化节点树。
-
-
TwigExtensionStringLoaderExtension:定义
template_from_string
- 函数允许从模板中的字符串加载模板。
-
TwigExtensionStringLoaderExtension:定义
Core、Escaper和Optimizer扩展在默认情况下是注册的。
内置的扩展
本节描述内置扩展添加的特性。
提示
阅读关于延长枝学习如何创建自己的扩展。
排放器扩展
的逃脱者
扩展添加自动输出转义到树枝。它定义了一个标签,autoescape
,和一个过滤器,生
.
当创建escaper扩展时,你可以打开或关闭全局输出转义策略:
1 2
$逃脱者=新\ \树枝\扩展EscaperExtension (“html”);$嫩枝->addExtension ($逃脱者);
如果设置为超文本标记语言
时,模板中的所有变量都将转义(使用超文本标记语言
逃跑策略),除了那些使用生
过滤器:
1
{{article.to_html |生}}
属性也可以在本地更改转义模式autoescape
标签:
1 2 3 4 5
{%autoescape“html”%}{{var}}{{var |生}}{# var不转义#}{{var |逃避}}{# var不会被双转义#}{%endautoescape%}
警告
的autoescape
标记对包含的文件没有影响。
转义规则实现如下:
在模板中直接作为变量或过滤器参数使用的字面量(整数,布尔值,数组,…)永远不会自动转义:
1 2 3 4
{{"Twig
"}}{#不会被转义#}{%集text = "树枝
" %}{{text}}{#将转义#}结果为字面量或标记为safe的变量的表达式永远不会自动转义:
1 2 3 4 5 6 7 8
{{foo ?"Twig
": "
Twig"}}{#不会被转义#}{%集text = "树枝
" %}{{真的吗?text: "
Twig"}}{#将转义#}{{false ?text: "
Twig"}}{#不会被转义#}{%集text = "树枝
" %}{{foo ?文本|生: "
Twig"}}{#不会被转义#}对象具有
__toString
方法被转换为字符串并转义。你可以标记一些类和/或接口为安全的某些策略通过EscaperExtension: addSafeClass ()
:1 2 3 4 5 6 7 8 9 10 11
//标记类Foo对象为安全的HTML策略$escaper->addSafeClass('Foo', [' HTML ']);//标记接口Foo对象为安全的HTML策略$escaper->addSafeClass('FooInterface', [' HTML ']);//标记类Foo对象为安全的HTML和JS策略$escaper->addSafeClass('Foo', [' HTML ', ' JS ']);$escaper->addSafeClass('Foo', ['all']);
转义应用在打印之前,任何其他过滤器应用之后:
1
{{var |上}}{#等价于{{var|upper|escape}} #}
' raw '过滤器应该只在过滤器链的末端使用:
1 2 3
{{var |生|上}}{#将转义#}{{var |上|生}}{#不会被转义#}
如果链中的最后一个过滤器对于当前上下文被标记为安全,则不会应用自动转义。
超文本标记语言
或js
).逃避
而且逃避(html)
标记为HTML安全,逃避(js)
对JavaScript来说是安全的,生
标志着一切安全。1 2 3 4 5
{%autoescapejs的%}{{var |逃避(html)}}{#将转义HTML和JavaScript #}{{var}}{#将转义为JavaScript #}{{var |逃避(js)}}{#不会被双转义#}{%endautoescape%}
请注意
请注意,自动转义有一些限制,因为转义应用于求值后的表达式。例如,当使用连接时,{{foo|raw ~ bar}}
不会给出预期的结果,因为转义应用于连接的结果,而不是单个变量(因此,生
滤镜在这里没有任何效果)。
沙箱扩展
的沙盒
扩展可用于计算不受信任的代码。禁止访问不安全的属性和方法。沙箱安全性由策略实例管理。默认情况下,Twig带有一个策略类:\树枝\沙箱\ SecurityPolicy
.这个类允许你列出一些标签、过滤器、属性和方法:
1 2 3 4 5 6 7 8 9 10
$标签= (“如果”];$过滤器= (“上”];$方法= (“文章”= > [“getTitle”,“getBody”]];$属性= (“文章”= > [“标题”,“身体”]];$功能= (“范围”];$政策=新\树枝\沙箱\ SecurityPolicy ($标签,$过滤器,$方法,$属性,$功能);
的配置,安全策略将只允许使用如果
标签,而上
过滤器。而且,模板将只能调用getTitle ()
而且getBody ()
上的方法文章
对象,以及标题
而且身体
公共属性。其他的都不允许并且会生成\树枝\沙箱\ SecurityError
例外。
策略对象是沙盒构造函数的第一个参数:
1 2
$沙盒=新\ \树枝\扩展SandboxExtension ($政策);$嫩枝->addExtension ($沙盒);
默认情况下,沙盒模式是禁用的,当使用沙盒
标签:
1 2 3
{%沙盒%}{%包括“user.html”%}{%endsandbox%}
你可以通过传递来沙盒所有模板真正的
作为扩展构造函数的第二个参数:
1
$沙盒=新\ \树枝\扩展SandboxExtension ($政策,真正的);
分析器扩展
的分析器
扩展可以为Twig模板提供分析器;它应该只在你的开发机器上使用,因为它会增加一些开销:
1 2 3 4 5
$配置文件=新\树枝\分析器\概要();$嫩枝->addExtension (新\ \树枝\扩展ProfilerExtension ($配置文件));$自动倾卸车=新\树枝\分析器\翻车机\ TextDumper ();回声$自动倾卸车->转储($配置文件);
概要文件包含关于模板、块和宏执行的时间和内存消耗的信息。
类型中转储数据Blackfire.io兼容的格式:
1 2
$自动倾卸车=新\树枝\分析器\翻车机\ BlackfireDumper ();写入“/道路/ / profile.prof”,$自动倾卸车->转储($配置文件));
上传概要文件以可视化它(创建一个免费帐户第一个):
1
Blackfire——slot=7 upload /path/to/profile.prof
优化器扩展
的优化器
扩展在编译前优化节点树:
1
$嫩枝->addExtension (新\ \树枝\扩展OptimizerExtension ());
默认情况下,所有优化都是打开的。你可以通过将它们传递给构造函数来选择你想要启用的:
1 2 3
$优化器=新\ \树枝\扩展OptimizerExtension(\树枝\ NodeVisitor \ OptimizerNodeVisitor::OPTIMIZE_FOR);$嫩枝->addExtension ($优化器);
Twig支持以下优化:
\树枝\ NodeVisitor \ OptimizerNodeVisitor:: OPTIMIZE_ALL
,启用所有优化(这是默认值)。\树枝\ NodeVisitor \ OptimizerNodeVisitor:: OPTIMIZE_NONE
,禁用所有优化。这减少了编译时间,但会增加执行时间和消耗的内存。\树枝\ NodeVisitor \ OptimizerNodeVisitor:: OPTIMIZE_FOR
,优化为
标记,删除循环
尽可能地创建变量。\树枝\ NodeVisitor \ OptimizerNodeVisitor:: OPTIMIZE_RAW_FILTER
,删除生
尽可能进行筛选。\树枝\ NodeVisitor \ OptimizerNodeVisitor:: OPTIMIZE_VAR_ACCESS
,尽可能简化编译模板中变量的创建和访问。
异常
Twig可以抛出异常:
\树枝\错误\错误
:所有错误的基本异常。\ \ SyntaxError树枝\错误
:抛出,告诉用户模板语法有问题。\ \ RuntimeError树枝\错误
:在运行时发生错误时抛出(例如,当过滤器不存在时)。\ \ LoaderError树枝\错误
:在模板加载过程中发生错误时抛出。\树枝\沙箱\ SecurityError
:当在沙盒模板中调用不允许的标记、过滤器或方法时抛出。