下面我将为你提供一个完整、详细的“织梦多条件筛选”模板和开发思路,分为【标准推荐方案】和【简单快速方案】两种,你可以根据自己的需求和技术能力选择。

(图片来源网络,侵删)
【核心概念】
无论哪种方案,多条件筛选的核心逻辑都是一样的:
-
前端(HTML/JS):
- 构建筛选表单(如品牌、价格区间、颜色等下拉框或复选框)。
- 用户选择条件后,通过JavaScript或直接表单提交,将这些条件作为参数传递给后端,通常使用URL的
GET方式传递,/plus/list.php?tid=1&brand=苹果&price=1000-3000。
-
后端(PHP):
- 接收前端传来的筛选参数。
- 根据这些参数,动态构建SQL查询语句的
WHERE子句。 - 执行查询,获取符合条件的数据列表。
- 将筛选条件“并回显到表单上,方便用户看到当前筛选状态。
-
分页处理:
(图片来源网络,侵删)- 这是织梦多筛选的难点,因为筛选条件会改变
COUNT(*)的总数,从而影响分页,必须确保分页链接中也包含了所有的筛选参数。
- 这是织梦多筛选的难点,因为筛选条件会改变
【方案一:标准推荐方案 - 自定义模型 + 修改PHP文件】
这个方案最灵活、最规范,适合长期维护和功能复杂的项目。
第一步:创建自定义模型(以产品为例)
- 后台登录:进入织梦后台 -> 核心 -> 内容模型管理 -> 添加新模型。
- 模型信息:
- 模型名称:
产品 - 模型表前缀:
dede_(保持默认) - 模型中文名称:
products
- 模型名称:
- 字段管理:点击你刚创建的模型,进入“字段管理”。
- 添加你需要筛选的字段,
brand(品牌):单行文本 或 下拉框(推荐)price(价格):数字color(颜色):下拉框 或 多选框guige(规格):多行文本
- 添加你需要筛选的字段,
- 生成模型:添加完所有字段后,点击“一键生成栏目”,然后点击“更新数据库”,织梦会自动为你创建数据表
dede_products和相应的字段。
第二步:修改列表页模板文件
假设你的列表页模板是 list_product.htm。
-
准备筛选表单:在模板的适当位置(通常是列表上方)添加筛选表单。
<form name="searchform" action="{dede:global.cfg_cmspath/}/plus/list.php" method="get"> <!-- 1. 必须包含当前栏目ID,这是织梦分页和列表的基础 --> <input type="hidden" name="tid" value="{dede:field.id/}" /> <!-- 2. 品牌筛选 (示例:从当前栏目下文章的brand字段获取所有值) --> <div> <label>品牌:</label> <select name="brand"> <option value="">全部</option> {dede:sql sql="SELECT DISTINCT brand FROM `dede_addonproducts` WHERE arcid IN (SELECT id FROM `dede_archives` WHERE typeid=~typeid~)"} <option value="[field:brand/]">[field:brand/]</option> {/dede:sql} </select> </div> <!-- 3. 价格筛选 (手动输入或使用JS生成) --> <div> <label>价格:</label> <input type="text" name="price_min" placeholder="最低价" value="{dede:global.item.price_min/}" /> <span>-</span> <input type="text" name="price_max" placeholder="最高价" value="{dede:global.item.price_max/}" /> </div> <!-- 4. 颜色筛选 (示例) --> <div> <label>颜色:</label> <input type="checkbox" name="color[]" value="红色" {dede:global.item.color.red runphp='yes'}@me=in_array("红色", explode(',', @me)) ? 'checked' : ''{/dede:global.item.color.red}/>红色 <input type="checkbox" name="color[]" value="蓝色" {dede:global.item.color.blue runphp='yes'}@me=in_array("蓝色", explode(',', @me)) ? 'checked' : ''{/dede:global.item.color.blue}/>蓝色 </div> <button type="submit">筛选</button> </form>代码解释:
(图片来源网络,侵删)tid={dede:field.id/}:这是关键,确保列表始终在正确的栏目下。{dede:global.item.xxx/}:这是用来回显筛选条件的。item是我们在PHP文件中定义的一个全局变量,用来存放当前所有筛选条件。{dede:global.item.price_min/}会显示用户之前输入的最低价。color[]:使用数组形式接收多选框的值。
第三步:修改PHP核心文件(最关键的一步)
这是实现筛选逻辑的核心,你需要修改织梦处理列表的PHP文件。强烈建议先备份原文件!
-
找到文件:
/plus/list.php,这是织梦处理所有列表请求的核心文件。 -
修改思路:
- 在文件开头,接收
$_GET过来的所有筛选参数(如brand,price_min,price_max,color等)。 - 初始化一个
$addsql变量,用来存放动态构建的SQLWHERE子句。 - 根据接收到的参数,逐步构建
$addsql。 - 将
$addsql变量传递给织梦的分页函数和列表查询函数。 - 将所有筛选参数存入一个全局数组,并赋值给
{dede:global/},以便在模板中回显。
- 在文件开头,接收
-
修改代码示例 (在
list.php中):// 在 list.php 文件中,找到大约在第200行左右的 //获得列表查询语句 这部分代码 // 1. 在文件开头,接收并处理筛选参数 $brand = isset($_GET['brand']) && trim($_GET['brand']) ? trim($_GET['brand']) : ''; $price_min = isset($_GET['price_min']) && is_numeric($_GET['price_min']) ? intval($_GET['price_min']) : 0; $price_max = isset($_GET['price_max']) && is_numeric($_GET['price_max']) ? intval($_GET['price_max']) : 0; $colors = isset($_GET['color']) && is_array($_GET['color']) ? $_GET['color'] : array(); // 2. 初始化 $addsql $addsql = " WHERE 1=1 "; // 3. 动态构建 WHERE 子句 if ($brand) { $addsql .= " AND a.brand = '{$brand}' "; } if ($price_min > 0) { $addsql .= " AND a.price >= {$price_min} "; } if ($price_max > 0) { $addsql .= " AND a.price <= {$price_max} "; } if (!empty($colors)) { // 对于多选,使用 IN 或 FIND_IN_SET $color_str = "('" . implode("','", $colors) . "')"; $addsql .= " AND a.color IN {$color_str} "; // 或者使用 FIND_IN_SET: $addsql .= " AND FIND_IN_SET('{$color_str}', a.color) > 0 "; } // 4. 将筛选条件存入全局变量,供模板回显 $GLOBALS['item'] = array( 'brand' => $brand, 'price_min' => $price_min, 'price_max' => $price_max, 'color' => array_flip($colors) // 转换为键值对,方便模板判断 ); // 5. 找到织梦原有的查询语句,将 $addsql 拼接进去 // 大约在 220 行左右,找到类似这样的代码: // $cquery = "SELECT id,typename,ispart,defaultname,namerule2,moresite,siteurl,sitepath // FROM `dede_arctype` WHERE reid='$typeid' And ishidden<>1 order by sortrank asc limit 0, $typeid "; // 在它下面,找到获取总数和列表的SQL,并修改: // --- 获取总数SQL --- $sql = "SELECT COUNT(*) AS dd FROM `dede_archives` arc LEFT JOIN `dede_addonproducts` add ON arc.id = add.arcid {$addsql}"; $row = $dsql->GetOne($sql); $TotalResult = $row['dd']; // --- 获取列表SQL --- // 假设你的附加表是 dede_addonproducts $sql = "SELECT arc.*, add.* FROM `dede_archives` arc LEFT JOIN `dede_addonproducts` add ON arc.id = add.arcid {$addsql} ORDER BY arc.sortrank DESC"; $dsql->SetQuery($sql); $dsql->Execute('list'); // 执行查询 // 6. 修改分页函数调用,确保分页链接带上筛选参数 // 找到分页函数调用,通常在文件末尾 // $pageList = pageList($totalResult, $getpagenow, $list_len, $listitem, $rule); // 你需要手动构建 $rule 参数,或者修改分页函数本身,一个简单的方法是修改分页URL生成逻辑。 // 一个更简单但“笨”的方法是,在生成分页链接后,用正则表达式把筛选参数加进去。 // 这部分比较复杂,推荐使用现成的分页类插件或深入研究织梦分页机制。 // 一个更简单的分页处理思路: // 在调用 `pageList()` 之前,先构建一个基础URL,包含所有筛选参数 $base_url = $cfg_phpurl."/list.php?tid={$typeid}"; foreach ($_GET as $k => $v) { if ($k != 'tid' && $k != 'pageno') { // 排除tid和分页参数 $base_url .= "&{$k}=".urlencode($v); } } // 然后修改 `pageList` 函数的调用,传入这个 $base_url 作为基础URL(这通常需要修改 `inc_fun_funAdmin.php` 里的 `pageList` 函数) // 或者,直接在这里重写分页逻辑,不使用织梦自带的函数。
注意:修改 list.php 是侵入式操作,升级织梦时可能会被覆盖,修改前务必备份。
【方案二:简单快速方案 - 自定义表单 + JS筛选】
这个方案不修改核心PHP文件,利用自定义表单和前端JS实现,适合筛选条件简单、不想动后端的场景。
第一步:创建自定义表单
- 后台 -> 核心 -> 自定义表单 -> 添加新的表单。
- 表单名称:
products_filter - 添加字段:和方案一一样,添加
brand,price,color等字段。 - 生成表单:点击“生成表单”,得到表单代码。
第二步:创建列表模板
-
创建一个普通的文章列表模板,
list_simple.htm。 -
获取数据:使用
{dede:arclist}标签获取所有文章。注意:这里不做任何后端筛选,所有数据都会被查出。<h1>产品列表</h1> <!-- 筛选表单(来自自定义表单,稍作修改) --> <div class="filter-box"> <form id="filterForm"> <!-- 从自定义表单代码中复制过来,并修改action和name --> <select name="brand"> <option value="">全部品牌</option> <!-- 这里可以写死选项,或者再用一个SQL循环 --> <option value="苹果">苹果</option> <option value="华为">华为</option> </select> <input type="text" name="price" placeholder="输入价格"> <button type="button" onclick="doFilter()">筛选</button> </form> </div> <!-- 列表区域,给每个列表项加上自定义属性 --> <ul class="product-list" id="productList"> {dede:arclist row='20' channelid='1'} <!-- channelid是你创建的产品模型ID --> <li data-brand="[field:brand/]" data-price="[field:price/]"> <a href="[field:arcurl/]"> <img src="[field:litpic/]" alt="[field:title/]"> <h3>[field:title/]</h3> <p>品牌:[field:brand/]</p> <p>价格:[field:price/]元</p> </a> </li> {/dede:arclist} </ul>
第三步:编写前端JavaScript
在模板的底部 <body> 标签后,引入jQuery(如果还没引入),并编写筛选脚本。
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
function doFilter() {
// 1. 获取筛选条件
var brand = $('#filterForm select[name="brand"]').val();
var price = $('#filterForm input[name="price"]').val();
// 2. 遍历列表项,根据条件显示/隐藏
$('#productList li').each(function() {
var $this = $(this);
var show = true; // 默认显示
// 品牌筛选
if (brand && $this.data('brand') != brand) {
show = false;
}
// 价格筛选 (简单示例,实际可以更复杂,如区间)
if (price && $this.data('price') != price) {
show = false;
}
// 应用显示/隐藏
$this.toggle(show);
});
}
</script>
方案二优缺点:
- 优点:
- 无需修改PHP文件,安全,升级无忧。
- 实现简单,快速。
- 缺点:
- 性能差:所有数据都在页面加载时就从数据库取出来了,如果数据量大,页面会非常卡顿。
- 功能受限:无法实现分页、排序等依赖后端的功能。
- URL不友好:筛选结果无法通过URL分享和收藏。
总结与建议
| 特性 | 方案一 (修改PHP) | 方案二 (JS筛选) |
|---|---|---|
| 实现复杂度 | 高,需要PHP和SQL知识 | 低,只需HTML和JS知识 |
| 性能 | 高,只在后端查询符合条件的数据 | 低,前端加载所有数据,用JS过滤 |
| 可扩展性 | 强,可轻松添加分页、排序、AJAX加载等 | 弱,功能局限于前端展示 |
| URL状态 | 好,筛选结果可通过URL分享和收藏 | 差,URL不会改变,无法分享状态 |
| 维护性 | 差,升级织梦可能覆盖修改 | 好,与系统核心解耦 |
最终建议:
- 对于任何正式的、数据量可能增长的项目,请务必选择【方案一】,虽然前期投入大,但它是专业和正确的做法。
- 对于临时的、数据量极少(几十条以内)的展示页面,或者只是一个快速原型验证,可以考虑使用【方案二】来快速实现效果。
希望这个详细的模板和思路能帮助你成功实现织梦的多条件筛选功能!
