Grav CMS子导航实现咨询:为自定义主题开发子导航
我来帮你完善这个Grav主题的子导航功能!从你给出的代码片段来看,你已经找对了方向——用Twig宏来递归遍历页面层级是Grav中实现多级导航的最佳实践之一。我把你的代码补全并优化,让它能完整实现带下拉效果的子导航:
完整的子导航Twig代码
{% block navigation %} {# 定义递归宏来遍历页面层级 #} {% macro loop(page) %} {% for p in page.children %} {% if p.visible %} {% set active_class = (p.active or p.activeChild) ? 'active' : '' %} {# 如果当前页面有子页面,渲染下拉菜单结构 #} {% if p.children.count > 0 %} <div class="nav-item dropdown {{ active_class }}"> <a href="{{ p.url }}" class="btn btn-nav dropdown-toggle" role="button" data-bs-toggle="dropdown" aria-expanded="false"> {{ p.menu ?: p.title }} </a> <div class="dropdown-menu"> {# 递归调用宏渲染子页面 #} {{ _self.loop(p) }} </div> </div> {% else %} {# 没有子页面,直接渲染普通导航项 #} <div class="nav-item {{ active_class }}"> <a href="{{ p.url }}" class="btn btn-nav" role="button"> {{ p.menu ?: p.title }} </a> </div> {% endif %} {% endif %} {% endfor %} {% endmacro %} {# 调用宏,从当前页面的顶级父页面开始渲染(或者直接用page.root) #} <div class="nav-container"> {{ _self.loop(page.closest('root')) }} </div> {% endblock %}
关键细节说明
- 页面可见性判断:通过
p.visible过滤掉后台设置为不可见的页面,确保导航只展示公开内容 - 激活状态处理:
active_class会自动给当前页面或其子页面添加active类,方便你用CSS高亮当前位置 - 菜单文本 fallback:用
{{ p.menu ?: p.title }}优先显示页面的自定义菜单名称,没有的话就用页面标题,更灵活 - Bootstrap 兼容:代码里用了Bootstrap 5的下拉菜单属性(
data-bs-toggle),如果你的主题用的是其他框架,只需要替换对应的触发属性和样式类即可 - 递归遍历:宏的递归调用
{{ _self.loop(p) }}可以无限嵌套处理多级子页面,不管你的页面层级有多深都能适配
如果需要调整导航的起始层级(比如从当前页面的直接父级开始渲染),只需要把page.closest('root')改成page.parent就行啦!
内容的提问来源于stack exchange,提问作者joelluethi
相关产品推荐
相关产品推荐

