在内容日益丰富的网站上,如何帮助访客快速找到他们感兴趣的信息,是提升用户体验和网站效率的关键。传统的固定分类导航往往难以满足用户多维度、个性化的筛选需求。这时候,AnQiCMS提供的archiveFilters标签便能大显身手,它能帮助我们动态展示多维度的内容筛选条件,让您的网站内容管理与呈现更加灵活和智能。
设想一下,如果您的网站上发布了大量的房源信息、商品列表或是行业报告,访客可能不仅仅想通过“区域”或“分类”来查找,他们可能希望同时根据“价格区间”、“房型”、“发布日期”或“报告类型”、“行业领域”等多种条件进行组合筛选。手动维护这些复杂的筛选组合几乎是不可能完成的任务,而archiveFilters正是为了解决这类挑战而设计的。
搭建多维度筛选的基础:理解内容模型与自定义字段
要让archiveFilters标签发挥作用,我们首先需要为内容奠定一个良好的结构基础,这便是AnQiCMS强大之处——灵活的内容模型。在后台的“内容模型”管理中,您可以根据业务需求创建或修改模型,例如“房产模型”、“产品模型”或“行业报告模型”。
每个内容模型都可以自定义多个字段。这些自定义字段正是我们构建多维度筛选条件的核心。例如,在“房产模型”中,您可以添加“房型”(单选:一居室、两居室等)、“区域”(下拉选择:城南、城北等)、“价格区间”(单行文本或数字范围)、“发布年份”(数字)等字段。在发布具体内容时,运营人员只需要填充这些字段,archiveFilters就能自动识别这些字段并将其转换为可供访客选择的筛选条件。
自定义字段支持多种类型,例如单行文本、数字、多行文本,以及更适合做筛选的单项选择、多项选择和下拉选择。对于筛选功能而言,我们通常会选择后三种类型,它们允许我们预设好选项,方便系统生成精准的筛选条件。
archiveFilters标签的核心功能与参数解析
archiveFilters标签的主要职责,就是在前端页面上动态地渲染出您在后台内容模型中定义的筛选字段及其对应的选项。它通常会与文档列表标签archiveList和分页标签pagination配合使用,构成一个完整的筛选体验。
让我们来看看这个标签的基本使用方式:
{% archiveFilters filters with moduleId="1" allText="全部" %}
{# 在这里循环输出筛选条件 #}
{% endarchiveFilters %}
这里有几个重要的参数需要了解:
filters:这是您为筛选结果集定义的变量名。通过这个变量,您可以在标签内部循环访问所有生成的筛选条件及其选项。moduleId:这个参数非常关键,它告诉archiveFilters您希望基于哪个内容模型来生成筛选条件。例如,moduleId="1"通常对应后台默认的文章模型,moduleId="2"可能对应产品模型。您需要根据自己的实际模型ID来设置,以确保筛选条件与内容匹配。allText:当访客首次进入筛选页面,或者想取消某个筛选条件时,通常会有一个“全部”或“不限”的选项。allText参数就是用来设置这个文本内容的。如果您不希望显示这个选项,可以设置为allText=false。siteId:如果您使用了AnQiCMS的多站点管理功能,并且希望调用其他站点的数据进行筛选,可以通过siteId来指定。对于大多数单站点用户而言,这个参数通常不需要手动填写。
filters这个变量本身是一个数组对象,它包含了每个筛选字段的信息。对其中的每个item(即一个筛选字段),您会发现以下几个关键属性:
Name:这是筛选字段的中文显示名称,例如“房型”、“区域”。FieldName:这是筛选字段在数据库中的实际字段名,例如“house_type”、“area”。Items:这是一个内嵌的数组,包含了该筛选字段所有可供选择的选项。
而Items数组中的每个val(即一个筛选选项)又包含了:
Label:这是筛选选项的中文显示文本,例如“一居室”、“城南”。Link:这是点击该筛选选项后,跳转到的带有相应筛选参数的URL地址。AnQiCMS会自动为您构建这个URL。IsCurrent:这是一个布尔值,表示当前这个选项是否已经被选中。这对于前端样式高亮显示当前筛选状态非常有用。
实践出真知:构建一个动态筛选界面
理解了基础概念后,我们通过一个实际的代码片段来展示archiveFilters如何与archiveList和pagination标签协同工作,创建一个完整的动态筛选界面。假设我们有一个房产列表页面,需要根据“房型”和“区域”进行筛选。
{# 1. 首先,渲染动态筛选条件区域 #}
<div class="filter-section">
<h3 class="visually-hidden">内容筛选</h3>
{% archiveFilters filters with moduleId="1" allText="不限" %}
{% for item in filters %}
<div class="filter-group">
<span class="filter-label">{{ item.Name }}: </span>
<ul class="filter-options">
{% for val in item.Items %}
<li class="filter-option {% if val.IsCurrent %}active{% endif %}">
<a href="{{ val.Link }}">{{ val.Label }}</a>
</li>
{% endfor %}
</ul>
</div>
{% endfor %}
{% endarchiveFilters %}
</div>
{# 2. 接着,渲染文档列表以显示筛选结果 #}
<div class="archive-list-area">
{% archiveList archives with moduleId="1" type="page" limit="10" %}
{% for item in archives %}
<div class="archive-item">
<a href="{{ item.Link }}">
<h4>{{ item.Title }}</h4>
<p>{{ item.Description|truncatechars:100 }}</p>
<div class="meta">
<span>分类: {% categoryDetail with name="Title" id=item.CategoryId %}</span>
<span>发布日期: {{ stampToDate(item.CreatedTime, "2006-01-02") }}</span>
<span>浏览量: {{ item.Views }}</span>
</div>
</a>
{% if item.Thumb %}
<a href="{{ item.Link }}" class="archive-thumb">
<img src="{{ item.Thumb }}" alt="{{ item.Title }}">
</a>
{% endif %}
</div>
{% empty %}
<p class="no-content">当前筛选条件下没有找到相关内容。</p>
{% endfor %}
{% endarchiveList %}
</div>
{# 3. 最后,添加分页功能 #}
<div class="pagination-area">
{% pagination pages with show="5" %}
<ul class="pagination-list">
<li class="page-item {% if pages.FirstPage.IsCurrent %}active{% endif %}">
<a href="{{ pages.FirstPage.Link }}">{{ pages.FirstPage.Name }}</a>
</li>
{% if pages.PrevPage %}
<li class="page-item"><a href="{{ pages.PrevPage.Link }}">{{ pages.PrevPage.Name }}</a></li>
{% endif %}
{% for item in pages.Pages %}
<li class="page-item {% if item.IsCurrent %}active{% endif %}">
<a href="{{ item.Link }}">{{ item.Name }}</a>
</li>
{% endfor %}
{% if pages.NextPage %}
<li class="page-item"><a href="{{ pages.NextPage.Link }}">{{ pages.NextPage.Name }}</a></li>
{% endif %}
<li class="page-item {% if pages.LastPage.IsCurrent %}active{% endif %}">
<a href="{{ pages.LastPage.Link }}">{{ pages.LastPage.Name }}</a>
</li>
</ul>
{% endpagination %}
</div>
在上面的代码中,archiveFilters生成了所有可能的筛选选项。每个选项的val.Link会自动包含当前页面