velocity-subtemplate-variable-fix
为什么你的 Velocity 子模板变量总是失效一行代码解决了阅读前提你正在用 Velocity 做模板引擎开发主模板能正常渲染但子模板里一用变量就报空指针或者路径找不到。先说我的血泪史昨晚被一个问题折磨了两个小时主模板引用子模板#parse($!relPath/S01/S0101.vm)子模板里我想引用公共宏#parse($!relPath/common/macro.vm)——结果运行时子模板里$!relPath直接变成空字符串文件找不到页面崩了。我第一反应是是不是变量名写错了检查了十几遍没毛病。又怀疑是不是 Velocity 版本问题换了个版本问题依旧。最后发现真相的时候我只想翻白眼 ——Velocity 的 #parse 根本不会自动把主模板的变量传递给子模板。问题根因Velocity 的#parse和#include有一个非常反直觉的设计子模板是独立执行的它不会继承主模板中的变量上下文。也就是说你在主模板里#set($!relPath templates/tdt)子模板里$!relPath依然是null。这和大多数人的预期完全相反。解决方案在 Java 代码里往 context 中塞变量而不是在模板里 set// TdtEntQueryServiceImpl.javapublicStringrenderTemplate(...){// 省略其他代码...// 设置模板路径前缀用于子模板引用StringrelPathTEMPLATE_FILE.substring(0,TEMPLATE_FILE.lastIndexOf(/));context.put(relPath,relPath);// 继续正常渲染...}主模板里直接用#parse($!relPath/$!section.categoryCode/$!subSection.productCode.vm)子模板里也能正常拿到$!relPath了。为什么在代码里 set 而不是模板里 set方式子模板能拿到吗推荐度主模板#set($!relPath xxx)❌ 不能⭐Java 代码context.put(relPath, ...)✅ 可以⭐⭐⭐⭐⭐核心原因#set只在当前模板作用域生效#parse引入的子模板是全新的上下文。扩展公共宏文件也得用完整路径公共宏文件同理必须在子模板里写完整路径#parse($!relPath/common/macro.vm)经验总结Velocity 的变量作用域比想象中更隔离——不要假设子模板能看到主模板的上下文跨模板共享变量扔到 context 里——这是唯一靠谱的方式#parse 和 #include 是两回事——前者解析执行模板后者只做文件引入不会解析变量踩坑提示如果你正在用 Velocity 做报告生成或者类似的模板渲染遇到了子模板变量失效的问题先检查变量是在 Java 代码的 context 里 set 的还是在主模板里 #set 的子模板里引用的路径是不是完整路径确认用的是 #parse 而不是 #include希望这篇文章能帮你少走两个小时弯路。你有遇到过类似的模板引擎坑吗欢迎留言交流
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2456760.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!