Twig模板循环按group_name分组实现组名置顶显示方法
Twig实现分组列表(组名置顶+组内项排列)方案
你现有代码存在3个核心问题:
- 未做分组判断,遍历每一项都会输出组名,导致组名重复出现在每个州条目上方
- 代码末尾多余
{% endif %}标签,没有对应匹配的{% if %}开头,会触发Twig语法报错 - 原始数组中同分组数据存在不连续的情况(示例数据中id=6的usa项排在aus分组条目后),直接遍历会导致同组内容被拆分
推荐方案:后端先聚合分组数据(性能最优)
最稳妥的实现方式是在数据传给Twig前,先按group_name字段做聚合,把同分组的州归到同一结构下,Twig层直接两层循环渲染即可。
PHP端预处理代码示例:
$groupedPlaces = []; foreach ($places as $place) { // 对象写法调用取组名方法,数组写法直接取键值 $groupKey = is_object($place) ? $place->getGroupName() : $place['group_name']; if (!isset($groupedPlaces[$groupKey])) { $groupedPlaces[$groupKey] = [ 'group_name' => strtoupper($groupKey), 'states' => [] ]; } // 对应取state字段 $stateVal = is_object($place) ? $place->getState() : $place['state']; $groupedPlaces[$groupKey]['states'][] = $stateVal; } // 转成索引数组传给模板 $groupedPlaces = array_values($groupedPlaces);
Twig模板渲染代码:
<table> {% for group in groupedPlaces %} {# 每个分组顶部仅打印一次组名 #} <tr> <td><strong>Group Name: {{ group.group_name }}</strong></td> </tr> {# 循环输出当前分组下所有州 #} {% for state in group.states %} <tr> <td>State: {{ state }}</td> </tr> {% endfor %} {# 分组之间加空行实现独立展示效果 #} <tr> <td> </td> </tr> {% endfor %} </table>
备选方案:Twig层单循环判断分组(无需改后端)
如果暂时无法调整后端数据逻辑,可以在Twig层先对原数组按分组名排序,再通过记录上一分组名的方式判断是否需要打印组头。
注意:必须先对数组按
group_name排序,保证同分组数据连续,否则会出现同组被拆分、组名重复打印的问题
{% set lastGroup = null %} <table> {# 先按分组名排序,保证同组数据连续 #} {% for place in places|sort((a, b) => a.group_name <=> b.group_name) %} {# 首次遍历、或当前项和上一项分组不一致时,打印组名 #} {% if lastGroup != place.group_name %} {% if lastGroup is not null %} {# 上一个分组结束,插入空行分隔 #} <tr><td> </td></tr> {% endif %} <tr> <td><strong>Group Name: {{ place.group_name|upper }}</strong></td> </tr> {% set lastGroup = place.group_name %} {% endif %} {# 打印当前州条目 #} <tr> <td>State: {{ place.state }}</td> </tr> {% endfor %} </table>
上述两种方案最终渲染效果完全匹配需求:每个分组名固定在所属州列表的最顶部,组下按顺序排列所有对应州,不同分组之间有空行分隔独立展示。
内容的提问来源于stack exchange,提问作者Lim lee
相关产品推荐
相关产品推荐

