在网站运营中,为文章列表提供灵活的多条件筛选功能,能极大地提升用户体验和内容的可发现性。安企CMS(AnQiCMS)凭借其强大的内容模型和丰富的模板标签,让构建这样的功能变得直观而高效。下面,我们将深入探讨如何一步步在AnQiCMS中实现文章列表的多条件筛选并展示结果。
核心基石:灵活的内容模型与自定义字段
在AnQiCMS中,多条件筛选功能的实现,首先得益于其“灵活的内容模型”设计。这意味着您可以根据业务需求,为不同类型的内容(如文章、产品)创建自定义的模型,并在这些模型下定义各种“自定义字段”。这些自定义字段是构建筛选功能的基础。
例如,如果您正在运营一个房产信息网站,您可能需要为“房源”内容模型添加“房屋类型”(如公寓、别墅、商铺)、“户型”(如一室一厅、两室两厅)、“所在区域”和“装修情况”等字段。当您在后台的“内容管理”模块下,进入“内容模型”设置,选择或创建一个模型后,便可以轻松添加这些字段。对于需要作为筛选条件的字段,尤其推荐使用“单项选择”、“多项选择”或“下拉选择”类型,这样可以预定义可选值,便于用户进行精确筛选。这些预设的值不仅方便内容录入,也为前端筛选提供了明确的选项。
当这些自定义字段被创建并应用到您的内容模型后,您发布的每篇文章或产品都将包含这些附加信息,从而为后续的筛选奠定数据基础。
构建筛选界面:巧妙运用 archiveFilters 标签
有了自定义字段作为数据支撑,接下来就是在前端页面上构建筛选界面。安企CMS提供了 archiveFilters 模板标签,专门用于动态生成基于这些自定义字段的筛选条件。
archiveFilters 标签的用法非常灵活。您只需指定内容模型的ID(moduleId),系统便能自动识别该模型下所有可用于筛选的自定义字段,并根据这些字段的预设值生成筛选选项。例如,如果您想在文章列表页为ID为1的文章模型构建筛选器,可以这样使用:
{% archiveFilters filters with moduleId="1" allText="全部" %}
<div class="filter-section">
{% for item in filters %}
<div class="filter-group">
<span class="filter-name">{{ item.Name }}:</span>
<ul class="filter-options">
{% for val in item.Items %}
<li class="{% if val.IsCurrent %}active{% endif %}">
<a href="{{ val.Link }}">{{ val.Label }}</a>
</li>
{% endfor %}
</ul>
</div>
{% endfor %}
</div>
{% endarchiveFilters %}
在这段代码中:
filters是我们自定义的变量名,用于接收archiveFilters返回的筛选数据。moduleId="1"指定了要筛选的文章模型ID。allText="全部"定义了显示“全部”选项的文本。- 外层
for item in filters循环遍历了每个筛选维度(例如“房屋类型”、“户型”)。 - 内层
for val in item.Items循环遍历了每个筛选维度下的具体选项(例如“公寓”、“别墅”)。 val.Link是自动生成的、带有相应筛选参数的URL,点击即可完成筛选。val.IsCurrent用于判断当前选项是否被选中,方便通过CSS高亮显示活动筛选条件。
通过这样的结构,您无需手动编写每个筛选条件的URL,AnQiCMS会智能地为您生成,极大地简化了开发流程。当用户点击某个筛选选项时,页面会跳转到带有相应查询参数的URL,例如 http://yourdomain.com/list/articles/?房屋类型=公寓&户型=两室一厅。
展示筛选结果:archiveList 标签的强大威力
当用户通过 archiveFilters 生成的链接进行筛选后,页面会携带查询参数重新加载。此时,archiveList 标签便会发挥其强大的作用来展示符合筛选条件的文章列表。
archiveList 是AnQiCMS用于获取文章列表的核心标签。它不仅可以根据分类ID、模型ID、推荐属性等常规条件获取文章,更重要的是,当 type="page" 时,它能够自动解析URL中的查询参数,将这些参数作为筛选条件,并返回符合条件的分页文章列表。这意味着,您在URL中传递的自定义字段筛选参数(例如 ?房屋类型=公寓)会被 archiveList 自动识别和应用。
以下是一个典型的 archiveList 用于展示筛选结果的代码片段:
<div class="article-list">
{% archiveList archives with type="page" moduleId="1" limit="10" %}
{% for item in archives %}
<div class="article-item">
<a href="{{ item.Link }}">
<img src="{{ item.Thumb }}" alt="{{ item.Title }}" />
<h3>{{ item.Title }}</h3>
<p>{{ item.Description }}</p>
</a>
<span>发布时间: {{ stampToDate(item.CreatedTime, "2006-01-02") }}</span>
<span>浏览量: {{ item.Views }}</span>
{# 还可以显示自定义字段,例如房产的“房屋类型” #}
{% archiveParams params with id=item.Id sorted=false %}
{% if params.房屋类型 %}
<span>房屋类型: {{ params.房屋类型.Value }}</span>
{% endif %}
{% endarchiveParams %}
</div>
{% empty %}
<p>抱歉,没有找到符合条件的文章。</p>
{% endfor %}
{% endarchiveList %}
{# 别忘了加上分页导航 #}
{% pagination pages with show="5" %}
<div class="pagination-nav">
{% if pages.PrevPage %}<a href="{{ pages.PrevPage.Link }}">上一页</a>{% endif %}
{% for item in pages.Pages %}<a class="{% if item.IsCurrent %}current{% endif %}" href="{{ item.Link }}">{{ item.Name }}</a>{% endfor %}
{% if pages.NextPage %}<a href="{{ pages.NextPage.Link }}">下一页</a>{% endif %}
</div>
{% endpagination %}
</div>
在这个例子中:
moduleId="1"确保只从指定模型中获取文章。type="page"启用分页功能,并且是关键,它使得archiveList能够自动读取URL中的筛选参数。limit="10"设置每页显示的文章数量。archiveParams标签可用于在文章列表中显示每篇文章的特定自定义字段值。pagination标签则负责生成美观的分页导航,这些分页链接同样会保留当前的筛选条件。
实际操作示例:以房产网站为例
假设我们有一个房产网站,其“房源”模型(moduleId=2)包含以下自定义字段:
house_type(房屋类型): 单项选择,选项有“公寓”、“别墅”、“商铺”layout(户型): 单项选择,选项有“一室一厅”、“两室两厅”、“三室两厅”decoration(装修情况): 单项选择,选项有“毛坯”、“简装”、“精装”
要在房源列表页实现这些筛选功能,您可以这样组织模板代码:
”`twig {# 房源列表页模板:house/list.html #} <!DOCTYPE html>
<meta charset="UTF-8">
<title>{% tdk with name="Title" siteName=true %}</title>
<link rel="stylesheet" href="/static/css/style.css">
<header>...</header>
<main>
<div class="container">
<h1>房源列表</h1>
{# 筛选区域 #}
<div class="filter-area">
{% archiveFilters house_filters with moduleId="2" allText="不限" %}
{% for item in house_filters %}
<div class="filter-group">
<span class="filter-label">{{ item.Name }}:</span>
<div class="filter-options">
{% for val in item.Items %}
<a href="{{ val.Link }}" class="filter-item {% if val.IsCurrent %}active{% endif %}">
{{ val.Label }}
</a>
{% endfor %}
</div>
</div>
{% endfor %}
{% endarchiveFilters %}
</div>
{# 房源列表展示 #}
<div class="house-listings">
{% archiveList houses with type="page" moduleId="2" limit="8" %}
{% for house in houses %}
<div class="house-card">
<a href="{{ house.Link }}">
{% if house.Thumb %}<img src="{{ house.Thumb }}" alt="{{ house.Title }}" class="house-thumb">{% endif %}
<h3>{{ house.Title }}</h3>
{% archiveParams house_params with id=house.Id sorted=false %}
<p>房屋类型: {{ house_params.house_type.Value }}</p>
<p>户型: {{ house_params.layout.Value }}</p>
<p>装修情况: {{ house_params.decoration.Value }}</p>
{% endarchiveParams %}
</a>
</div>
{% empty %}
<p class="no-results">根据您的筛选条件,暂时没有找到合适的房源。</p>
{% endfor %}
{% endarchiveList %}
</div>
{# 分页导航 #}
<div class="pagination-wrapper">
{% pagination pager with show="5" %}
{% if pager.TotalPages > 1 %}
<a href="{{ pager.FirstPage.Link }}" class="pager-link {% if pager.FirstPage.IsCurrent %}current{% endif %}">首页</a>
{% if pager.PrevPage %}<a href="{{ pager.PrevPage.Link }}" class="pager-link">上一页</a>{% endif %}
{% for p_item in pager.Pages %}
<a href="{{ p_item.Link }}" class="pager-link {% if p_