如何在Twig中提取内联JS并移至文档末尾完成项目重构?
在Twig中收集内联JS并统一输出到文档末尾
当然可以实现!Twig的扩展机制和变量传递能力正好能满足你的需求,下面是一套贴合你现有代码结构的完整实现方案:
1. 给Twig注册自定义函数,对接你的Document类
首先在PHP代码里,给Twig添加一个自定义函数,用来把模板里的JS代码存入你已经定义好的Document实例:
// 注册Twig自定义函数 $twig->addFunction(new Twig\TwigFunction('add_inline_js', function (string $jsCode, Document $document) { // 这里可以选择只存JS核心代码,最后统一包裹<script>标签(推荐) $document->addInlineJS($jsCode); // 返回空字符串,避免在模板调用位置输出多余内容 return ''; }));
如果你想保留完整的<script>标签结构(比如带type属性或其他参数),也可以直接传入完整标签内容,后续输出时直接渲染即可。
2. 修改Twig模板,替换内联JS代码
把原来模板里的内联<script>块,换成调用这个自定义函数:
<!-- Template.twig --> <div> <p>Text</p> <p>More text</p> </div> {# 替换原来的<script>标签,传入JS代码和document实例 #} {{ add_inline_js("(function(){ console.log('Some random javascript..') })();", document) }}
如果要保留完整标签:
{{ add_inline_js("<script type='text/javascript'> (function(){ console.log('Some random javascript..') })(); </script>", document) }}
3. 在文档末尾统一输出收集到的JS
在你的基础模板(比如base.twig)的</body>标签前,遍历输出所有收集到的JS代码:
<!-- base.twig --> <body> {% block content %}{% endblock %} {# 输出所有收集的内联JS,用raw过滤器避免Twig转义代码 #} {% for js in document.getInlineJS() %} {{ js|raw }} {% endfor %} </body>
4. 完整渲染流程(和你的原有逻辑兼容)
你的PHP渲染代码可以保持原有结构,现在$document->getInlineJS()就能拿到所有模板里收集的JS了:
<?php class Document{ private $inlineJS = array(); public function addInlineJS($code){ $this->inlineJS[] = $code; } public function getInlineJS(){ return $this->inlineJS; } } $document = new Document(); $template = $twig->loadTemplate('template.twig'); $output = $template->render(['document' => $document]); // 如需在PHP中额外处理JS,直接调用即可 $allCollectedJs = $document->getInlineJS();
进阶备选:用Twig块实现(无需额外PHP类)
如果你的场景更简单,不想依赖Document类,也可以用Twig的块机制:
- 在基础模板定义一个
inline_js块:
<!-- base.twig --> {% block inline_js %}{% endblock %} </body>
- 在子模板里往这个块追加内容:
<!-- Template.twig --> {% extends 'base.twig' %} {% block content %} <div> <p>Text</p> <p>More text</p> </div> {% endblock %} {% block inline_js %} {{ parent() }} {# 保留父块原有内容 #} <script type="text/javascript"> (function(){ console.log('Some random javascript..') })(); </script> {% endblock %}
这种方式更轻量化,但灵活性稍弱(只能在块中添加JS,无法在模板任意位置收集)。
内容的提问来源于stack exchange,提问作者nikksan
相关产品推荐
相关产品推荐

