如何在Wagtail模板中为多个StreamField块统一包裹外层类?
解决Wagtail中连续同类型块统一包裹容器的问题
方法一:纯模板层面实现(无需修改后端)
利用模板变量跟踪当前是否处于游戏块组中,动态控制容器的开闭:
{% with in_game_group=False %} {% for block in page.body %} {% if block.block_type == 'game' %} {% if not in_game_group %} <div class="row-grid"> {% with in_game_group=True %} {% endif %} {% include_block block %} {% else %} {% if in_game_group %} </div> {% with in_game_group=False %} {% endif %} {% include_block block %} {% endif %} {% endfor %} <!-- 处理最后一组未闭合的游戏块容器 --> {% if in_game_group %} </div> {% endif %} {% endwith %}
代码说明:
in_game_group变量标记当前是否已打开row-grid容器- 遇到第一个游戏块时打开容器,后续连续游戏块直接渲染,不重复创建容器
- 遇到非游戏块时,若之前处于游戏块组,先闭合容器再渲染当前块
- 遍历结束后检查状态,确保容器最终正确闭合
方法二:后端分组后渲染(逻辑更清晰)
在页面模型中添加分组方法,将连续的游戏块打包为一组,其他块单独成组:
# models.py from wagtail.models import Page class YourPageModel(Page): # 页面字段定义... def get_grouped_blocks(self): groups = [] current_game_blocks = [] for block in self.body: if block.block_type == 'game': current_game_blocks.append(block) else: # 先处理未完成的游戏块组 if current_game_blocks: groups.append(('game_group', current_game_blocks)) current_game_blocks = [] # 添加非游戏块为单独组 groups.append(('single_block', [block])) # 处理最后一组剩余的游戏块 if current_game_blocks: groups.append(('game_group', current_game_blocks)) return groups
然后在模板中遍历分组结果:
{% for group_type, blocks in page.get_grouped_blocks %} {% if group_type == 'game_group' %} <div class="row-grid"> {% for block in blocks %} {% include_block block %} {% endfor %} </div> {% else %} {% include_block blocks.0 %} {% endif %} {% endfor %}
优势:
- 分组逻辑从模板剥离,代码更易维护
- 后续调整分组规则仅需修改后端方法即可
内容的提问来源于stack exchange,提问作者Vlad
相关产品推荐
相关产品推荐

