网站的导航系统如同建筑的骨架,它不仅引导用户浏览,更直接影响内容的曝光度和搜索引擎优化。AnQiCMS 提供了灵活强大的导航管理功能,让您轻松构建多级菜单,并实现与网站内容的深度联动,从而提升用户体验和内容分发效率。

灵活配置,构建多级导航骨架

在 AnQiCMS 中,实现多级菜单的起点在于后台的导航设置。您可以在“后台设置”下的“导航设置”中找到所有关于网站导航的配置项。

首先,系统默认提供了一个“默认导航”类别,但如果您有更多样化的需求,比如网站顶部主导航、页脚导航、侧边栏导航等,AnQiCMS 允许您通过“导航类别管理”新增多个自定义类别。这为您的网站提供了极大的灵活性,可以为不同位置设置独立的导航结构。

在添加或编辑具体的导航链接时,几个关键的设置项决定了多级菜单的实现。每一个导航链接都可以指定一个“上级导航”,这正是构建多级菜单的核心。如果您将“上级导航”设置为“顶级导航”,它便会作为一级菜单显示;如果选择一个已存在的一级菜单作为其上级,它便自然成为二级菜单。目前 AnQiCMS 支持最多两级导航链接,足以满足大多数网站的需求。

“链接类型”的设定则确保了导航与内容的联动。您可以选择“内置链接”来指向首页或特定模型(如文章、产品)的首页;选择“分类页面链接”来直接关联已创建的文章分类、产品分类或单页面;而“外部链接”则提供了最大的自由度,可以指向任何站内或站外的 URL。这些选项让您的导航不仅仅是简单的文字链接,而是网站内容架构的直接体现。

模板实现:navList 标签的强大力量

后台配置好导航结构后,接下来需要在前端模板中将其呈现出来。AnQiCMS 采用类似 Django 模板引擎的语法,让模板制作直观高效。核心的导航渲染标签便是 navList

通过 {% navList navs %} 标签,您可以获取到后台配置的所有导航数据。navs 变量是一个包含导航条目(item)的数组,您可以遍历它来生成菜单。

一个典型的多级菜单结构,可以通过 navList 标签配合 for 循环和条件判断轻松实现。每个 item 都可能包含一个 NavList 属性,这个属性同样是一个数组,存储着当前导航项的下级菜单数据。通过嵌套的 for 循环,您可以完美地构建出二级菜单:

{% navList navs %}
<ul class="main-nav">
    {%- for item in navs %}
        <li class="{% if item.IsCurrent %}active{% endif %}">
            <a href="{{ item.Link }}">{{item.Title}}</a>
            {%- if item.NavList %} {# 判断是否有下级导航 #}
            <dl class="sub-nav">
                {%- for inner in item.NavList %}
                    <dd class="{% if inner.IsCurrent %}active{% endif %}">
                        <a href="{{ inner.Link }}">{{inner.Title}}</a>
                    </dd>
                {% endfor %}
            </dl>
            {% endif %}
        </li>
    {% endfor %}
</ul>
{% endnavList %}

在上面的代码中,item.IsCurrent 属性会帮助您判断当前导航项是否为当前页面,进而添加 active 类名,提升用户体验。

内容联动:让菜单“活”起来

仅仅显示链接文字可能还不够,有时您希望在鼠标悬停或点击二级菜单时,能够直接展示与该菜单项关联的动态内容,比如某个分类下的最新文章或热门产品。AnQiCMS 的 navList 标签结合 archiveListcategoryList 等内容标签,能轻松实现这种内容联动。

每个导航项 item 都可能包含一个 PageId 属性,它关联着后台设置的分类或单页面的 ID。利用这个 PageId,您可以在二级菜单甚至更深层级中,动态调用相关内容。

例如,如果您希望在二级产品分类菜单下,直接展示该分类的最新产品列表,可以这样操作:

<ul>
    {% navList navList with typeId=1 %} {# 假设typeId=1是您的主导航 #}
    {%- for item in navList %}
    <li>
        <a href="{{ item.Link }}">{{item.Title}}</a>
        {%- if item.NavList %}
        <ul class="nav-menu-child">
            {%- for inner in item.NavList %}
            <li>
                <a href="{{ inner.Link }}">{{inner.Title}}</a>
                {% if inner.PageId > 0 %} {# 确保该导航项关联了内容ID #}
                    {% archiveList products with type="list" categoryId=inner.PageId limit="8" %} {# 联动显示该分类下最新的8个产品 #}
                    {% if products %}
                    <ul class="nav-menu-child-products">
                        {% for product in products %}
                        <li><a href="{{product.Link}}">{{product.Title}}</a></li>
                        {% endfor %}
                    </ul>
                    {% endif %}
                    {% endarchiveList %}
                {% endif %}
            </li>
            {% endfor %}
        </ul>
        {% endif %}
    </li>
    {% endfor %}
    {% endnavList %}
</ul>

这段代码首先遍历主导航,如果一级导航有下级(二级导航),它会继续遍历二级导航。对于每个二级导航项,如果它关联了一个 PageId(通常是某个分类的ID),就会使用 archiveList 标签来获取该分类下的最新产品(moduleId 需根据实际产品模型ID调整,这里未显式给出,假设 inner.PageId 对应产品分类)。通过这种方式,用户在导航菜单中就能直接预览到关联内容,大大提升了浏览效率。

另一个常见的场景是在导航中显示某个分类的下级分类。这同样可以通过 categoryList 标签实现:

<ul>
    {% navList navList with typeId=1 %}
    {%- for item in navList %}
    <li>
        <a href="{{ item.Link }}">{{item.Title}}</a>
        {%- if item.NavList %}
        <ul class="nav-menu-child">
            {%- for inner in item.NavList %}
            <li>
                <a href="{{ inner.Link }}">{{inner.Title}}</a>
                {% if inner.PageId > 0 %}
                    {% categoryList categories with parentId=inner.PageId %} {# 显示该分类的下级分类 #}
                    {% if categories %}
                    <ul class="nav-menu-child-subcategories">
                        {% for subCategory in categories %}
                        <li>
                            <a href="{{ subCategory.Link }}">{{subCategory.Title}}</a>
                        </li>
                        {% endfor %}
                    </ul>
                    {% endif %}
                    {% endcategoryList %}
                {% endif %}
            </li>
            {% endfor %}
        </ul>
        {% endif %}
    </li>
    {% endfor %}
    {% endnavList %}
</ul>

这里,如果二级导航项关联了某个分类ID,categoryList 标签将获取并展示该分类下的所有子分类。

实用技巧与注意事项

  • 模块化模板: 为了保持代码的整洁和可维护性,建议将导航代码片段单独存放在 partial/ 目录下(例如 partial/header_nav.html),然后通过 {% include "partial/header_nav.html" %} 标签在主模板中引用,这与 AnQiCMS 的模板约定相符。
  • CSS 和 JavaScript: 导航菜单的最终展现效果,包括下拉动画、响应式布局等,都依赖于您精心编写的 CSS 样式和 JavaScript 交互逻辑。AnQiCMS 提供了灵活的模板结构,但具体的样式和行为需要前端代码来完成。
  • 伪静态规则: 确保您的网站伪静态