首页/新闻资讯/正文详情

Twig `include` 函数实战指南:模板包含、上下文传递与缺失模板处理

发布时间:2026/9/26 19:12:26 来源:云帆数科 栏目:资讯中心
Twig `include` 函数实战指南:模板包含、上下文传递与缺失模板处理
后端【免费下载链接】TwigTwig, the flexible, fast, and secure template language for PHP项目地址https://gitcode.com/gh_mirrors/tw/Twig点击查看免费下载导读include是 Twig 模板语言中用于在模板内渲染另一个模板的核心函数它返回被包含模板的渲染结果可用于拆分页面片段partial、复用组件或按条件动态选择模板。本文以doc/functions/include.rst为骨架结合src/Extension/CoreExtension.php中include()/includeOnly()的底层实现与tests/Fixtures/functions/include/下 17 个功能测试用例系统讲解include的用法、参数语义、上下文传递规则、缺失模板容错以及与include_only、render_sandboxed的选型差异。读完本文你将能正确使用include组织模板结构并理解其在 Twig 内部的渲染与转义行为。基本用法渲染一个模板include函数返回指定模板渲染后的内容而不是像{% include %}标签那样把输出直接写入当前流{{ include(template.html.twig) }} {{ include(some_var) }}模板名可以是一个字符串字面量也可以是一个表达式如变量some_varTwig 会在运行时求值。被包含的模板默认可以访问**当前上下文active context**中的所有变量。与标签形式不同函数形式把渲染结果作为值返回因此可以存入变量、传给过滤器或参与其他运算{% set tmp include(foo.twig) %} FOO{{ tmp }}BAR对应测试 tests/Fixtures/functions/include/assignment.test 展示了这一用法set语句捕获返回内容后再原样打印。从源码实现看include函数的注册位于 src/Extension/CoreExtension.php声明为new TwigFunction(include, [self::class, include], [needs_environment true, needs_context true, is_safe [all]]),其中needs_context表明该函数需要访问当前上下文这正是它默认把整个 context 传给被包含模板的原因而is_safe [all]表示函数返回的内容被标记为安全的见下文返回值与自动转义一节。传递额外变量默认情况下当前上下文会被原样传递给被包含的模板但你也可以传入额外的变量它们会合并进被包含模板的变量空间{# 被包含的模板可以访问 name 以及当前上下文中的全部变量 #} {{ include(template.html.twig, {name: Fabien}) }}实现上这一步发生在 src/Extension/CoreExtension.phpif ($withContext) { $variables array_merge($context, $variables); }即先以当前上下文为底再把你显式传入的变量覆盖/追加进去然后一次性交给被包含模板渲染。关闭上下文传递with_context: false如果不希望被包含的模板访问调用方的整个上下文可以把with_context设为false{# 只有 name 变量可以被访问 #} {{ include(template.html.twig, {name: Fabien}, with_context: false) }}测试 tests/Fixtures/functions/include/with_context.test 精确验证了这一行为它让被包含模板遍历并打印_context中的所有键。当数据为[foo bar]时{{ include(foo.twig) }}输出foo,global,_parent,——当前上下文变量全部可见{{ include(foo.twig, with_context false) }}输出global,_parent,——foo不再可见{{ include(foo.twig, {foo1: bar}) }}输出foo,global,foo1,_parent,——显式变量foo1与上下文变量foo同时存在{{ include(foo.twig, {foo1: bar}, with_context false) }}输出foo1,global,_parent,——只有显式传入的变量可用。注意global与_parent始终存在global是注册到环境上的全局变量_parent是模板自动提供的父上下文引用它们不受with_context影响include_only一节还会再讨论这一点。返回值与自动转义include函数返回的内容通常是\Twig\Markup实例即被标记为安全的字符串存入变量后再输出不会被再次转义{% set body include(body.html.twig) %} {{ body }} {# 原样输出不会二次转义 #}对应实现见 src/Extension/CoreExtension.php$rendered $loaded-render($variables); return $rendered ? : new Markup($rendered, $env-getCharset());渲染结果为空字符串时返回普通空串否则包装成Markup。测试 tests/Fixtures/functions/include/autoescaping.test 与assignment_autoescaping.test验证了在启用自动转义autoescape的情况下被包含模板按其自身声明的转义策略渲染外层不再重复转义。⚠️ 需要留意正因为返回值是安全值它不会针对其最终所处的上下文重新转义。请只在与其渲染时的上下文通常是 HTML相同的场景中嵌入该返回值例如不要把为 HTML 渲染的结果直接放进 JavaScript 或 URL 环境。缺失模板处理ignore_missing与模板列表静默降级默认情况下如果被包含的模板不存在Twig 会抛出LoaderError异常。设置ignore_missing: true后缺失的模板会被忽略函数返回空字符串{{ include(sidebar.html.twig, ignore_missing: true) }}实现位于 src/Extension/CoreExtension.phptry { $loaded $env-resolveTemplate($template); } catch (LoaderError $e) { if (!$ignoreMissing) { throw $e; } return ; }测试 tests/Fixtures/functions/include/ignore_missing.test 覆盖了ignore_missing与with_context、variables的各种组合缺失模板时全部静默输出空内容。按列表逐个尝试template参数还可以是一个模板名数组Twig 会按顺序检查渲染第一个存在的模板{{ include([page_detailed.html.twig, page.html.twig]) }}此时若设置了ignore_missing则当列表中的所有模板都不存在时什么都不渲染否则抛出异常。底层由 src/Environment.php 的resolveTemplate()驱动foreach ($names as $name) { if (1 ! $count !$this-getLoader()-exists($name)) { continue; } return $this-load($name); } throw new LoaderError(...);resolveTemplate()也接受Template或TemplateWrapper实例作为候选项。测试 tests/Fixtures/functions/include/templates_as_array.test 验证了数组回退逻辑[foo.twig, bar.twig]渲染 foo[bar.twig, foo.twig]同样渲染存在的 fooignore_missing_exists.test 与 missing.test、missing_nested.test 分别覆盖了存在与缺失两种走向。传入模板实例除了模板名字符串include也接受\Twig\TemplateWrapper实例——由$twig-load()得到后作为变量传入即可{{ include(template) }}$template $twig-load(some_template.html.twig); $twig-display(template.html.twig, [template $template]);测试 tests/Fixtures/functions/include/template_instance.test 即通过$twig-load(foo.twig)构造数据并渲染成功。这适合在 PHP 侧预先解析好模板、再交给 Twig 模板复用的场景。模板加载规则include使用当前环境配置的加载器loader解析模板。如果使用 FilesystemLoader则在 loader 定义的路径列表中按顺序查找如果使用 ArrayLoader如测试夹具中的--TEMPLATE(foo.twig)--块则直接按名称在内存数组中解析。自定义 loader 只需实现 LoaderInterface 即可被include透明使用。安全提醒渲染不可信模板要加沙箱被包含的模板若由最终用户创建不可信内容应当进行沙箱化处理。官方推荐方式并非include的sandboxed参数而是从受信任的模板中调用render_sandboxed()函数或从 PHP 侧使用Twig\Sandbox\Sandbox类直接渲染不可信模板。sandboxed参数已弃用Twig 3.29 起include的sandboxed参数自 Twig 3.29 起被弃用。源码 src/Extension/CoreExtension.php 中只要传入第 7 个位置参数就会触发弃用通知deprecation传true提示改用render_sandboxed渲染不可信模板传false则提示该参数已无意义、应删除。正确的替代方案推荐方案一是 PHP 侧沙箱使用Twig\Sandbox\Sandbox类包装安全策略后渲染模板方案二是模板侧调用render_sandboxed它在 Twig 3.29 引入通过专用的沙箱渲染不可信模板且不会自动继承受信任模板的上下文{{ render_sandboxed(newsletter.twig, {name: name}, html) }}其中第二个参数是传给沙箱模板的完整上下文第三个参数声明输出转义策略——结果仅对该策略安全若用于其他转义上下文 Twig 会再次转义注意该策略不会对输出做净化声明html意味着不可信作者写的 HTML 会原样到达响应仅在明确需要时使用。要启用它需要在受信任环境上注册SandboxBridgeExtension并注入懒加载的SandboxBridgeRuntime具体注册方式见 SandboxBridgeExtension 源码 与 SandboxBridgeRuntime 源码。选型建议include与include_onlyTwig 3.29 新增了include_only()函数官方明确建议能用include_only就优先用它。原因是共享整个上下文会让被包含模板悄悄依赖调用方定义的变量从而隐藏其真实输入、把它耦合到任何包含它的位置。include_only只接收你显式传入的变量使数据流清晰可见partial 更容易复用。{# include_only 不隐式传递当前上下文 #} {{ include_only(template.html.twig, {name: Fabien}) }} {# 从当前上下文取同名变量时可使用快捷语法 #} {{ include_only(template.html.twig, {name, email}) }} {# 等价于 {name: name, email: email} #}二者共享模板加载、ignore_missing、数组回退及返回值Markup行为区别仅在于include_only没有with_context/sandboxed参数——实现上它直接以空上下文调用include()public static function includeOnly(Environment $env, $template, array $variables [], bool $ignoreMissing false) { return self::include($env, [], $template, $variables, false, $ignoreMissing); }注意include_only同样不包含全局变量——通过Environment::addGlobal()注册的全局变量不属于上下文因此在被包含模板中仍然可用。参数一览include函数完整参数如下与 doc/functions/include.rst 一致参数说明默认值template要渲染的模板模板名字符串、字符串数组按序取第一个存在的或TemplateWrapper实例必填variables传递给模板的变量映射与当前上下文合并[]with_context是否传递当前上下文变量trueignore_missing模板缺失时是否忽略并返回空字符串falsesandboxed是否对模板进行沙箱化自 3.29 弃用改用render_sandboxed/ PHP 侧Sandboxfalse对应函数签名为 src/Extension/CoreExtension.phppublic static function include(Environment $env, $context, $template, $variables [], $withContext true, $ignoreMissing false, $sandboxed false)延伸阅读include_only函数官方文档不共享上下文的模板包含推荐优先使用render_sandboxed函数官方文档渲染不可信模板的沙箱方案沙箱机制完整说明安全策略、可用标签/过滤器/函数白名单include 功能测试夹具目录17 个.test用例覆盖本函数全部行为可直接作为行为规范阅读。赞分享后端【免费下载链接】TwigTwig, the flexible, fast, and secure template language for PHP项目地址https://gitcode.com/gh_mirrors/tw/Twig点击查看免费下载相关推荐Twig 模板语言 include_only 函数详解显式传参、隔离上下文与安全包含Twig 模板语言 include_only 函数详解显式传参、隔离上下文与安全包含 导读 include_only 是 Twig 3.29 新增的内置函数后端chezmoi 模板函数 includeTemplate 完全指南复用 .chezmoitemplates 模板并传入上下文数据chezmoi 模板函数 includeTemplate 完全指南复用 .chezmoitemplates 模板并传入上下文数据 导读 includeTemp开发工具CLI配置管理5分钟告别手动安装BetterNCM Installer让你的网易云音乐焕然一新5分钟告别手动安装BetterNCM Installer让你的网易云音乐焕然一新 你是否厌倦了网易云音乐PC客户端功能单一、界面单调想要更多个性化设置却无从后端上一篇揭秘Windows与iPhone无缝连接一键驱动安装的全新体验下一篇KMS_VL_ALL_AIO3种创新方案彻底解决Windows和Office激活难题创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

WorkBuddy 从入门到高效协作:连接器、自定义指令与 Artifacts 实战指南
WorkBuddy 从入门到高效协作:连接器、自定义指令与 Artifacts 实战指南

1. 先搞清楚 WorkBuddy 到底解决什么问题很多人第一次接触 WorkBuddy,是被"AI智能助手"这个词吸引进来的,结果装完之后发现不知道拿它干什么。我一开始也是这样,把它当成一个聊天窗口用了两周,觉得不过如此。直到有一次… · 2026/9/26 19:12:20

群晖第三方硬盘不被识别?3步写进Synology硬盘兼容库
群晖第三方硬盘不被识别?3步写进Synology硬盘兼容库

群晖第三方硬盘不被识别?3步写进Synology硬盘兼容库 【免费下载链接】Synology_HDD_db Add your HDD, SSD and NVMe drives to your Synologys compatible drive database and a lot more 项目地址: https://gitcode.com/GitHub_Trending/sy/Synology_HDD_db … · 2026/9/26 19:12:20

七彩虹隐星P15原厂Windows11镜像恢复出厂开箱状态教程
七彩虹隐星P15原厂Windows11镜像恢复出厂开箱状态教程

笔记本这东西,用上半年一年,系统就慢慢“脏”了:开机启动项一堆,弹窗广告比桌面图标还勤快,风扇呼呼转但游戏加载就是慢半拍。这时候很多人第一反应是重装系统,但普通重装有个问题——装出来的系统和出厂时… · 2026/9/26 19:12:20

Claude Code源码泄露后,TaoToken教你用settings.json加固AI开发工具链
Claude Code源码泄露后,TaoToken教你用settings.json加固AI开发工具链

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 20:27:15

tgrep架构解析:HybridIndex+LiveIndex覆盖层如何实现微秒级索引热更新
tgrep架构解析:HybridIndex+LiveIndex覆盖层如何实现微秒级索引热更新

tgrep架构解析:HybridIndexLiveIndex覆盖层如何实现微秒级索引热更新 【免费下载链接】tgrep Trigram-indexed grep with a client/server architecture for fast regex search in large codebases locally 项目地址: https://gitcode.com/gh_mirrors/tg/tgrep … · 2026/9/26 20:27:15

用Python计算空气清新剂安全浓度:VOC超标、通风时长与香薰风险
用Python计算空气清新剂安全浓度:VOC超标、通风时长与香薰风险

先说我自己的一个转变。以前我总觉得空气清新剂这种东西能有什么风险,最多就是香味太冲、熏得慌,忍一忍也就过去了。直到有一次,我在一间通风很差的小办公室里,让人开了一台大容量喷雾香薰机,半小时不到,全… · 2026/9/26 20:27:01

Shell循环详解:for、while与until的自动化脚本实战
Shell循环详解:for、while与until的自动化脚本实战

1. 循环语句在Shell里到底解决什么问题我第一次正经考虑学Shell编程,是因为连着加班两个晚上,都在手动处理同一批日志文件。那时候我还在用最笨的办法:打开一个目录,逐个文件grep关键字,记下结果,再打开下一… · 2026/9/26 20:27:01

AI Agent冲击数据库:负载、权限、存储与治理的实战改造指南
AI Agent冲击数据库:负载、权限、存储与治理的实战改造指南

这两年做数据基础设施的人,应该都有一个很直观的感受:来自业务方的需求变味了。以前提的是“报表跑得慢”“接口超时”,现在开口就是“我们要给Agent开数据库权限”“Agent跑批的时候把生产库打满了”。我自己手上好几个项目,都在… · 2026/9/26 20:26:54

Spring Boot保险理赔管理系统:从需求分析到核心代码实现
Spring Boot保险理赔管理系统:从需求分析到核心代码实现

在毕业设计选题阶段,保险理赔管理系统一直是Spring Boot方向的热门选择。它不像电商、博客系统那样烂大街,又有足够真实的业务场景可以展开,既能体现数据库设计能力,又能展示业务逻辑的严谨性。这套系统本质上是在解决保险公司理赔… · 2026/9/26 20:26:54

数据库课后习题答案别硬背:当测试用例集刷,效率翻倍
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍

简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21

OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40

向下兼容与向上兼容:接口设计中的兼容性策略与工程实践
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践

一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码