在AnQiCMS模板中,如何通过with标签为include的导航模板传递特定变量?

作为一位深谙网站运营之道的专家,我经常遇到这样的需求:为了保持网站代码的整洁和可维护性,我们通常会将页头、页脚、侧边栏以及导航等常用模块拆分成独立的模板片段。安企CMS(AnQiCMS)凭借其基于Go语言的高效架构和Django模板引擎语法,为我们提供了极大的便利。然而,当这些通用模块需要在不同页面展示个性化内容时,如何灵活地传递特定变量,就成了一个关键点。今天,我们就来深入探讨在AnQiCMS模板中,如何巧妙地利用with标签为include的导航模板传递专属变量。

模块化模板:include标签的艺术

在AnQiCMS中,模板文件通常以.html为后缀,并存放在/template目录下的特定子文件夹中。为了实现代码复用,我们常常会将一些公共部分(比如导航菜单)抽取出来,放到像partial/这样的代码片段目录中。这样一来,任何需要显示导航的页面,只需简单地使用{% include "partial/nav.html" %}这样的标签,就能将导航模块引入进来,大大提升了开发效率和代码的可读性。

例如,我们可能有一个通用的导航模板partial/nav.html,它负责遍历后台配置的导航列表并渲染出来。这很棒,因为它确保了全站导航的一致性。但是,设想一下,如果某个页面需要导航高亮显示一个特定的菜单项,或者需要临时改变导航的某个标题,难道我们要为这个页面复制一份nav.html,然后去修改它吗?显然,这不是理想的解决方案。这时,with标签就派上用场了。

with标签的魔法:为include注入生命力

with标签在AnQiCMS模板中的主要作用是定义临时变量,这些变量仅在with标签的包裹范围内有效。但更强大的是,它可以作为include标签的参数,让我们在引入一个模板片段时,同时为其“注入”一些特定的数据或配置。这意味着,我们可以在不修改通用导航模板partial/nav.html的前提下,从外部传入参数,让它在不同场景下展现出不同的行为。

具体来说,当我们在主模板中使用{% include "partial/nav.html" ... %}时,可以通过添加with关键字,后跟一系列key="value"形式的参数,将这些变量传递给nav.html。这些变量在被include的模板中,就可以像普通变量一样被访问和使用了。

让我们通过一个实际的导航案例来理解这一点。

导航模板 (partial/nav.html)

假设我们的通用导航模板partial/nav.html长这样。它会尝试获取nav_title变量作为导航的头部标题,并通过active_item_id变量来判断哪个菜单项需要高亮显示。

{# partial/nav.html #}
<nav class="main-nav">
    <div class="nav-header">
        {# 如果外部传入了nav_title,则显示,否则显示默认标题 #}
        <h3>{{ nav_title|default:"网站主导航" }}</h3>
    </div>
    <ul>
        {%- navList mainNavs %}
        {%- for item in mainNavs %}
            {# 判断当前导航项是否是活跃状态,或者通过传入的active_item_id进行高亮 #}
            <li class="nav-item {% if item.IsCurrent or item.Id == active_item_id %}active{% endif %}">
                <a href="{{ item.Link }}">{{item.Title}}</a>
                {%- if item.NavList %}
                <ul class="sub-nav">
                    {%- for subItem in item.NavList %}
                        <li class="sub-nav-item {% if subItem.IsCurrent or subItem.Id == active_item_id %}active{% endif %}">
                            <a href="{{ subItem.Link }}">{{subItem.Title}}</a>
                        </li>
                    {% endfor %}
                </ul>
                {% endif %}
            </li>
        {% endfor %}
        {% endnavList %}
    </ul>
</nav>

在这个nav.html模板中,我们定义了两个期望从外部接收的变量:nav_titleactive_item_idnav_title在没有传入时会显示“网站主导航”作为默认值(这里使用了default过滤器,安企CMS支持多种过滤器)。active_item_id则用于判断哪个导航项需要添加active类,实现高亮效果。item.IsCurrent是安企CMS内置的,用于表示当前页面对应的导航项,而item.Id == active_item_id则允许我们通过传递ID来手动高亮。

调用导航模板 (index.htmlarticle_detail.html)

现在,假设我们有两个不同的页面:网站首页和某个文章详情页,它们都需要引入这个导航模板,但希望有不同的高亮效果和标题。

在首页 (index.html) 调用:

首页我们只想显示默认标题,并让“首页”菜单项高亮(假设其ID为1)。

{# index.html #}
{% extends 'base.html' %} {# 继承基础布局 #}

{% block content %}
    <main>
        <h1>欢迎来到安企CMS官网</h1>
        {# 引入导航模板,并传递active_item_id为1,高亮首页 #}
        {% include "partial/nav.html" with active_item_id=1 %}
        
        <section>
            {# 首页内容 #}
        </section>
    </main>
{% endblock %}

在文章详情页 (article_detail.html) 调用:

文章详情页可能属于“文章”分类(假设其ID为2),我们希望导航标题显示“最新文章”,并高亮文章分类。

{# article_detail.html #}
{% extends 'base.html' %} {# 继承基础布局 #}

{% block content %}
    <main>
        <h1>{{ archive.Title }}</h1>
        {# 引入导航模板,传递自定义标题和高亮文章分类(假设ID为2) #}
        {% include "partial/nav.html" with nav_title="最新文章" active_item_id=2 %}

        <article>
            {# 文章详情内容 #}
        </article>
    </main>
{% endblock %}

通过这样的方式,我们灵活地控制了partial/nav.html的行为,而无需复制或修改它本身。with标签让模板组件化和可定制化达到了一个新的高度。

进阶:only关键字的妙用

默认情况下,使用include时,被包含的模板会继承所有父模板的上下文变量。但在某些特定场景下,我们可能希望被包含的模板只接收通过with明确传递的变量,而忽略父模板的其他变量。这时,我们可以在with关键字后面加上only

{# 仅传递 active_item_id,不继承父模板的其他任何变量 #}
{% include "partial/nav.html" with active_item_id=1 only %}

使用only能够更严格地控制变量的作用域,避免意外的变量冲突,让模板片段更加独立和可预测。

总结

在AnQiCMS的模板开发中,include标签带来的模块化能力与with标签提供的变量传递机制相辅相成,为我们构建灵活、高效的网站提供了强大的工具。无论是简单的导航高亮,还是复杂的模块