Freemarker(FTL)中如何实现类似while循环的功能?
Freemarker while循环实现方案
基础结论
Freemarker 原生不支持 while 循环,仅内置了 <#list> 指令用于遍历序列、集合类数据,没有原生的条件循环指令,你需要通过自定义递归宏的方式模拟while效果。
适配你的场景的递归实现
你需要的等价于 while (myVariable != null) 的FTL实现代码如下:
<#-- 定义递归宏 --> <#macro myWhile> <#-- 每次循环先判断终止条件 --> <#if myVariable??> <#-- 此处放置循环体内要执行的操作 --> // 执行相关操作 <#-- 重要:必须添加更新myVariable的逻辑,否则会触发无限递归栈溢出,和JS while逻辑一致 --> <#-- 示例:<#assign myVariable = myVariable.parent /> 按照你的业务需求更新即可 --> <#-- 递归调用触发下一轮循环 --> <@myWhile /> </#if> </#macro> <#-- 调用宏启动循环 --> <@myWhile />
通用while宏实现
如果需要可复用的通用条件循环宏,可以参考以下实现,通过传入变量名的方式避免单次求值问题:
<#-- 通用while宏定义,varName为要判断非空的变量名(字符串类型) --> <#macro while varName> <#if .vars[varName]??> <#-- 执行调用时传入的循环体内容 --> <#nested> <@while varName=varName /> </#if> </#macro> <#-- 调用示例 --> <@while varName="myVariable"> // 执行相关操作 <#-- 记得更新myVariable的值 --> </@while>
注意事项
- 循环体内必须添加更新判断变量的逻辑,否则会触发无限递归导致模板渲染报错
- 递归深度不宜过大,FTL默认的递归深度限制一般在几千级,超量会触发栈溢出错误
内容的提问来源于stack exchange,提问作者Esteban Torres
相关产品推荐
相关产品推荐

