织梦专题页联动筛选如何实现?

99ANYc3cd6
预计阅读时长 34 分钟
位置: 首页 织梦建站 正文

根据用户选择的第一个条件(如一级分类),动态加载并更新第二个条件(如二级分类或标签)的可选项,并根据最终的选择来展示内容。

下面我将通过一个“产品专题页”的例子,为你提供一个完整、可操作的步骤指南。


场景设定

假设我们要做一个“智能家居”专题页,包含以下筛选条件:

  1. 一级分类: 智能安防、智能照明、智能家电
  2. 二级分类:
    • 智能安防:智能门锁、摄像头、传感器
    • 智能照明:智能灯泡、灯带、开关
    • 智能家电:智能音箱、扫地机器人、空调
  3. 筛选结果: 根据用户选择的“一级分类”和“二级分类”,展示对应的产品列表。

实现步骤

整个过程分为四个主要部分:

  1. 数据准备: 在后台正确设置好栏目和文章(产品)。
  2. 模板制作: 编写包含筛选表单和结果列表的HTML模板。
  3. JS联动逻辑: 编写JavaScript代码实现“一级分类”选择后,“二级分类”的动态加载。
  4. PHP数据处理: 编织织梦的标签,根据筛选条件查询并展示结果。

第一步:数据准备

  1. 创建一级分类栏目:

    • 在织梦后台【栏目管理】中,创建一个顶级栏目,智能家居专题”。
    • 在“智能家居专题”下,创建三个子栏目,分别对应一级分类:
      • 智能安防 (栏目ID假设为 2)
      • 智能照明 (栏目ID假设为 3)
      • 智能家电 (栏目ID假设为 4)
  2. 创建二级分类栏目:

    • 进入“智能安防”栏目,创建其子栏目:
      • 智能门锁 (栏目ID假设为 5)
      • 摄像头 (栏目ID假设为 6)
      • 传感器 (栏目ID假设为 7)
    • 同理,为“智能照明”和“智能家电”创建各自的二级分类子栏目。
  3. 添加产品内容:

    • 将所有产品文章发布到对应的最末级的二级分类栏目中,一个“小米智能门锁”的文章,就应该发布到“智能安防”下的“智能门锁”栏目中。

关键点: 筛选的核心就是利用织梦的栏目ID,一级分类的值是其栏目ID,二级分类的值也是其栏目ID。


第二步:模板制作

在专题页模板文件(通常是 templets/plus/list_special_专题ID.htm 或你自定义的模板文件)中,编写如下HTML结构。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">智能家居专题</title>
    <script src="{dede:global.cfg_cmspath/}/static/js/jquery.min.js"></script> <!-- 确保引入了jQuery -->
</head>
<body>
<h1>智能家居专题</h1>
<!-- 筛选表单开始 -->
<div class="filter-form">
    <form id="filterForm" action="" method="get">
        <!-- 隐藏字段,用于传递专题ID,方便PHP获取 -->
        <input type="hidden" name="tid" value="{dede:geturl typeid='0'}" />
        <!-- 一级分类选择 -->
        <div class="filter-item">
            <label for="cat_1">一级分类:</label>
            <select name="cat_1" id="cat_1">
                <option value="0">请选择</option>
                {dede:channel type='son' typeid='1'}
                <option value="{dede:field.id/}">{dede:field.typename/}</option>
                {/dede:channel}
            </select>
        </div>
        <!-- 二级分类选择(初始为空,由JS动态填充) -->
        <div class="filter-item">
            <label for="cat_2">二级分类:</label>
            <select name="cat_2" id="cat_2">
                <option value="0">请先选择一级分类</option>
            </select>
        </div>
        <!-- 提交按钮(可以省略,用JS监听change事件) -->
        <button type="submit">筛选</button>
    </form>
</div>
<!-- 筛选表单结束 -->
<!-- 结果列表开始 -->
<div class="result-list">
    <!-- 这里将由织梦的列表标签填充内容 -->
    {dede:list pagesize='10'}
    <div class="item">
        <a href="[field:arcurl/]">[field:title/]</a>
    </div>
    {/dede:list}
    <!-- 分页 -->
    <div class="page">
        {dede:pagelist listsize='4'/}
    </div>
</div>
<!-- 结果列表结束 -->
</body>
</html>

代码解释:

  • {dede:channel type='son' typeid='1'}:这个标签用于输出一级分类。typeid='1' 指定了父栏目的ID(即“智能家居专题”的ID),type='son' 表示只输出其直接子栏目。
  • name="cat_1"name="cat_2":这两个是表单提交时的字段名,PHP端会通过它们获取用户选择的值。
  • value="{dede:field.id/}":一级分类的option值是其栏目的ID。
  • id="cat_1"id="cat_2":给select元素设置ID,方便JS进行操作。
  • {dede:list}:这是标准的织梦列表标签,用于显示筛选后的结果。

第三步:JS联动逻辑

在模板的</body>标签之前,添加以下JavaScript代码。

<script type="text/javascript">
$(document).ready(function(){
    // 一级分类选择框
    var cat1Select = $('#cat_1');
    // 二级分类选择框
    var cat2Select = $('#cat_2');
    // 当一级分类的值发生改变时
    cat1Select.change(function(){
        // 获取选中项的栏目ID
        var parent_id = $(this).val();
        // 如果用户选择了“请选择”(值为0),则清空二级分类并返回
        if (parent_id == 0) {
            cat2Select.empty();
            cat2Select.append('<option value="0">请先选择一级分类</option>');
            return;
        }
        // 清空二级分类下拉框,并显示一个加载提示
        cat2Select.empty();
        cat2Select.append('<option value="0">加载中...</option>');
        // 发送AJAX请求,请求服务器获取二级分类
        $.ajax({
            type: 'POST',
            url: '{dede:global.cfg_cmspath/}/plus/ajax_channel.php', // 织梦获取栏目的标准接口
            data: {
                'parentid': parent_id, // 传递一级分类的ID
                'type': 'sun',         // 获取子栏目
                '_ajax': 1            // 标记为AJAX请求
            },
            dataType: 'json', // 期望返回JSON数据
            success: function(data){
                // 请求成功,清空加载提示
                cat2Select.empty();
                // 如果返回的数据不为空,则循环生成option
                if (data && data.length > 0) {
                    cat2Select.append('<option value="0">请选择</option>');
                    $.each(data, function(i, item){
                        cat2Select.append('<option value="' + item.id + '">' + item.typename + '</option>');
                    });
                } else {
                    // 如果没有子分类,则显示提示
                    cat2Select.append('<option value="0">暂无二级分类</option>');
                }
            },
            error: function(){
                // 请求失败,显示错误信息
                cat2Select.empty();
                cat2Select.append('<option value="0">加载失败</option>');
            }
        });
    });
    // 可选:当二级分类改变时,自动提交表单
    cat2Select.change(function(){
        // 确保一级和二级都选择了有效的值
        if (cat1Select.val() != '0' && $(this).val() != '0') {
            $('#filterForm').submit();
        }
    });
});
</script>

代码解释:

  • $('#cat_1').change(...):监听一级分类下拉框的change事件。
  • $.ajax(...):这是核心,当一级分类选择后,通过AJAX请求 {dede:global.cfg_cmspath/}/plus/ajax_channel.php 这个文件。
  • 'parentid': parent_id:将选中的一级分类ID作为参数传递过去。
  • 'type': 'sun':告诉接口我们要获取子栏目。
  • dataType: 'json':织梦的这个接口会返回一个JSON格式的栏目列表,如 [{"id":5,"typename":"智能门锁"}, {"id":6,"typename":"摄像头"}]
  • success: function(data){...}:在AJAX请求成功后,解析返回的JSON数据,并动态地创建<option>元素,填充到二级分类下拉框中。
  • cat2Select.change(function(){ $('#filterForm').submit(); });:这是一个很好的用户体验优化,当用户选择完二级分类后,表单会自动提交,无需再点击“筛选”按钮。

第四步:PHP数据处理

现在需要修改 {dede:list} 标签,让它能够根据URL参数 cat_1cat_2 来筛选内容。

织梦的 {dede:list}{dede:arclist} 标签本身不支持直接传入自定义的WHERE条件,我们需要使用更灵活的 {dede:sql} 标签来手动构建SQL查询。

将模板中的 {dede:list} 部分替换为以下代码:

<!-- 结果列表开始 -->
<div class="result-list">
    <?php
    // 获取URL参数
    $cat_1 = isset($_GET['cat_1']) ? intval($_GET['cat_1']) : 0;
    $cat_2 = isset($_GET['cat_2']) ? intval($_GET['cat_2']) : 0;
    // 构建SQL查询条件
    $where = " WHERE arc.arcrank > -1 "; // 默认条件:已审核
    $typeid = 0; // 默认查询所有栏目
    if ($cat_2 > 0) {
        // 如果选择了二级分类,则直接按二级分类的ID查询
        $typeid = $cat_2;
    } elseif ($cat_1 > 0) {
        // 如果只选择了一级分类,则按一级分类的ID查询
        $typeid = $cat_1;
    }
    // 如果typeid不为0,则添加到查询条件中
    if ($typeid > 0) {
        $where .= " AND arc.typeid = '$typeid' ";
    }
    ?>
    {dede:sql sql='SELECT arc.id, arc.title, arc.litpic, arc.typeid, tp.typename
                   FROM dede_archives arc
                   LEFT JOIN dede_arctype tp ON arc.typeid = tp.id
                   [!--上面构建的where条件--]
                   ORDER BY arc.sortrank DESC, arc.id DESC
                   LIMIT 0, 10'}
    <div class="item">
        <a href="[field:arcurl/]">[field:title/]</a>
        <span>分类:[field:typename/]</span>
    </div>
    {/dede:sql}
    <!-- 分页 -->
    <!-- 注意:使用sql标签后,默认的分页标签 {dede:pagelist} 会失效,分页功能需要更复杂的PHP代码来实现,这里先省略。 -->
    <div class="page">
        <!-- 分页代码 -->
    </div>
</div>
<!-- 结果列表结束 -->

代码解释:

  1. <?php ... ?>:在织梦模板中嵌入PHP代码。
  2. isset($_GET['cat_1']):获取通过URL传递过来的筛选参数。
  3. intval(...):对获取的参数进行整数化处理,防止SQL注入。
  4. $where 变量:这是SQL查询的WHERE子句,我们初始化了一个基本条件 arc.arcrank > -1(只显示审核通过的文章)。
  5. 逻辑判断
    • 优先判断 $cat_2,如果用户选择了二级分类,$typeid 就等于二级分类的ID。
    • $cat_2 为空,但 $cat_1 不为空,$typeid 就等于一级分类的ID。
    • 如果两者都为空,$typeid 保持为0,表示不按栏目筛选。
  6. {dede:sql}:
    • sql='...':这里直接编写完整的SQL查询语句。
    • [!--上面构建的where条件--]:这是一个占位符,我们需要将PHP变量 $where 的值插入到这里,在织梦模板中,更规范的写法是直接将PHP逻辑放在标签外面,然后构建完整的SQL字符串。
  7. 分页问题:使用 {dede:sql} 实现分页比较麻烦,因为它不会自动计算总数和生成分页代码,对于数据量大的情况,建议使用 {dede:list} 并通过修改其底层 list.php 文件来实现动态筛选,但这涉及到文件修改,更复杂,对于专题页这种数据量通常不大的情况,手动分页或“加载更多”是更简单的方案。

最终优化与总结

  1. URL美化:默认提交的URL可能是 ...?tid=1&cat_1=2&cat_2=5,你可以通过织梦的“伪静态”或“路由”功能,将其美化成 .../cat_2/5/ 这样的形式,但这需要额外的配置。
  2. 无刷新筛选:上面的JS代码已经实现了无刷新加载二级分类,并且通过 change 事件实现了自动提交,整个筛选过程对用户来说是流畅的。
  3. 扩展性:这个方法可以轻松扩展到三级分类甚至更多,只需要在JS中再嵌套一层AJAX请求,PHP中再增加一个cat_3的判断逻辑即可。
  4. 性能:如果产品(文章)数量非常庞大,直接在dede_archives表里用typeid查询可能会变慢,可以考虑为typeid字段建立索引。

通过以上四个步骤,你就可以在织梦专题页中实现一个功能完善、用户体验良好的联动筛选功能了。

-- 展开阅读全文 --
头像
本地dede如何安装模板?
« 上一篇 昨天
织梦能还原哪些数据?
下一篇 » 昨天

相关文章

取消
微信二维码
支付宝二维码