如何类似wp_reset_query()销毁Liquid循环以恢复当前集合数据?
解决Liquid中集合模板页
collection对象被菜单循环覆盖的问题 这个问题我之前帮不少开发者踩过坑,本质是Liquid的模板级变量作用域在搞事情——你肯定是在菜单循环里用了collection作为循环变量名,直接覆盖了集合模板页自带的全局collection对象(也就是当前页面对应的集合)。循环结束后,collection变量会停留在最后一次循环的集合数据上,所以你再调用collection.title时,显示的就是菜单里最后一个集合的标题了。
两种解决思路,对应类似WordPress wp_reset_query()的效果:
1. 最推荐:修改循环变量名,避免覆盖
直接把循环里的变量名改成和全局collection不冲突的名字,比如menu_collection,同时注意通过link.object访问集合的属性(因为linklists里的链接对象本身不是集合,object属性才指向对应的集合实体):
{% for menu_collection in linklists.all-collections.links %} <!-- 输出集合标题和URL --> <h3><a href="{{ menu_collection.url }}">{{ menu_collection.title }}</a></h3> <!-- 输出集合关联标签 --> {% if menu_collection.object.all_tags.size > 0 %} <div class="tags"> {% for tag in menu_collection.object.all_tags %} <span class="tag">{{ tag }}</span> {% endfor %} </div> {% endif %} {% endfor %}
这样全局的collection对象完全不会被影响,在模板页任何地方调用collection.title都会是当前集合的标题。
2. 临时保存+恢复全局对象(适合无法改变量名的场景)
如果因为历史代码或其他原因不能改循环变量名,可以在循环开始前把全局的collection保存到临时变量里,循环结束后再赋值回去:
<!-- 先保存当前集合到临时变量 --> {% assign current_collection = collection %} <!-- 你的菜单循环(这里用了collection作为变量名,会覆盖全局对象) --> {% for collection in linklists.all-collections.links %} <a href="{{ collection.url }}">{{ collection.title }}</a> {% for tag in collection.object.all_tags %} {{ tag }} {% endfor %} {% endfor %} <!-- 恢复全局的collection对象 --> {% assign collection = current_collection %}
这就相当于手动实现了类似wp_reset_query()的重置效果,把collection变量恢复到循环前的状态。
补充说明
Liquid没有像WordPress那样专门的重置循环函数,因为它的变量作用域是模板级的,只要避免同名变量覆盖,或者手动保存恢复,就能解决这类问题。
内容的提问来源于stack exchange,提问作者SBWT
相关产品推荐
相关产品推荐

