ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

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

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),仅供参考
返回列表