dede联动二次开发如何实现具体功能扩展?

99ANYc3cd6
预计阅读时长 27 分钟
位置: 首页 DEDE建站 正文
  1. 修改默认的字段类型:将普通的表单字段改为联动类型。
  2. 自定义联动的数据源:根据你的业务需求,创建专属的联动数据。
  3. 在前台调用联动数据:在文章列表、内容页或搜索表单中,展示和利用这些联动数据。

下面我将分步、详细地讲解整个二次开发流程。

dede 联动二次开发
(图片来源网络,侵删)

第一步:理解联动类别的工作原理

在开始开发前,我们先搞清楚 DedeCMS 联动类别的核心组成部分:

  1. dede_sys_enum:这是联动类别的数据表,它存储了所有联动类目的具体数据。

    • evalue:值,如 "110000"(北京市)。
    • ename:显示名称,如 "北京市"。
    • eorder:排序,数字越小越靠前。
    • enumtype联动类别标识,这是关键!所有属于同一个联动的数据,enumtype 都是一样的,所有中国省份数据的 enumtype 可能都是 "shengfen"。
    • pisnull:是否为父级。0 表示不是(即子级),1 表示是(即父级,如省份)。
  2. 后台管理路径后台菜单 -> 核心 -> 联动类别,在这里你可以创建、编辑、删除联动类别,并为其数据,每创建一个联动类别,系统都会生成一个唯一的 enumtype

  3. 前台模板调用标签{dede:global name='listitem.linkage'/},这个标签主要用于搜索表单中,生成一个联动选择的下拉菜单。

    dede 联动二次开发
    (图片来源网络,侵删)
  4. 数据存储:当你在模型中添加一个“联动类型”的字段(如 shengshi),提交文章后,选中的联动值(如 "110000")会存储在文章附加表(如 dede_addonarticle)的对应字段中。


第二步:创建自定义联动类别(数据源)

假设我们要做一个“汽车品牌-车系”的联动。

  1. 登录 DedeCMS 后台
  2. 进入 核心 -> 联动类别
  3. 点击 [增加联动类别]
    • 类别名称:填写 汽车品牌
    • 类别目录:系统会自动生成一个英文标识,如 car_brand,这就是我们上面提到的 enumtype,你可以修改,但建议使用有意义的英文。
    • 是否开启:选择“是”。
    • 设置项:这里可以设置每一级选择的名称,比如第一级叫“选择品牌”,第二级叫“选择车系”。
  4. 点击 [保存]
  5. 现在进入 [数据管理] 标签页。
    • 在“请选择类别”下拉框中,选择你刚刚创建的 汽车品牌
    • 开始添加数据:
      • 第一级(品牌)
        • evalue: 1, ename: 宝马, eorder: 1, pisnull: 1 (注意,这里是1,表示它是父级)
        • evalue: 2, ename: 奔驰, eorder: 2, pisnull: 1
      • 第二级(车系)
        • evalue: 101, ename: 3系, eorder: 1, pisnull: 0 (注意,这里是0,表示它不是父级,并属于父级evalue为1的项)
        • evalue: 102, ename: 5系, eorder: 2, pisnull: 0
        • evalue: 201, ename: C级, eorder: 1, pisnull: 0
        • evalue: 202, ename: E级, eorder: 2, pisnull: 0
  6. 保存数据,现在你的 dede_sys_enum 表里就有了汽车品牌和车系的联动数据。

第三步:在内容模型中添加联动字段

现在我们需要让用户在发布文章时可以选择这个联动。

  1. 进入 后台 -> 核心 -> 内容模型管理
  2. 选择你要修改的模型(通常是“文章模型”),点击 [字段管理]
  3. 点击 [增加字段]
    • 字段名car_brand (必须为英文,与数据库字段名一致)。
    • 字段标识汽车品牌 (后台显示的名称)。
    • 字段类型联动类型
    • 联动类型:在下拉框中选择你刚刚创建的 汽车品牌
    • 是否显示在发布页:选择“是”。
    • 其他选项:如默认值、是否必填等,根据需要设置。
  4. 点击 [保存],系统会提示你更新表结构,点击“是”即可。

去发布一篇文章,你就会在表单中看到一个“汽车品牌”的联动选择了。

dede 联动二次开发
(图片来源网络,侵删)

第四步:前台调用与显示(核心二次开发)

这是最关键的一步,分为两种情况:

在文章列表页或内容页显示已选择的联动名称

假设你在文章中选择了“宝马”的“3系”,数据库里存的是 101,但你不想显示 101,想显示 “宝马 3系”。

方法:使用自定义函数

  1. 编写函数: 在你网站的 include/ 目录下新建一个文件,my_functions.php,然后在里面写一个函数来获取联动名称。

    // 文件路径: /include/my_functions.php
    function getLinkageName($value, $enumtype) {
        if (empty($value) || empty($enumtype)) {
            return '';
        }
        global $dsql;
        $row = $dsql->GetOne("SELECT ename FROM `dede_sys_enum` WHERE evalue = '{$value}' AND enumtype = '{$enumtype}'");
        if (is_array($row)) {
            return $row['ename'];
        } else {
            return $value; // 如果没找到,就返回原始值
        }
    }
  2. 引入函数文件: 在你需要调用这个函数的模板文件(如 article_list.htmarticle_article.htm)的最开头,加入以下代码:

    {dede:global name='env/include'}
    <script language="javascript" src="{dede:global name='cfg_phpurl'/}/img/js/jquery.js"></script>
    {/dede:global}
    {dede:include filename='my_functions.htm'/}

    注意:更好的做法是在 /include/common.inc.php 中引入,但为了不修改核心文件,在模板中引入更安全,你需要创建一个 /include/my_functions.htm 文件,里面只有一行:require_once(DEDEINC.'/my_functions.php');

  3. 在模板中使用函数: 假设你的联动字段名是 car_brand,联动类型 enumtypecar_brand,在模板中这样调用:

    <p>
        汽车品牌:{dede:field name='car_brand' function="getLinkageName(@me, 'car_brand')"/}
    </p>
    • @me 是 DedeCMS 模板引擎的当前变量值,在这里就是数据库存的 101
    • function="getLinkageName(@me, 'car_brand')" 的意思是,把 @me (即 101) 和 'car_brand' 作为参数,传给 getLinkageName 函数。
    • 最终前台就会显示 “3系”,如果你需要显示父级名称(品牌),你需要写一个更复杂的函数来递归查找。

制作一个基于联动的搜索表单

你想让用户在前台通过选择“品牌”和“车系”来筛选文章。

  1. 准备模板: 在你的搜索表单模板(如 search.htm)中,加入以下代码:

    <form name="formsearch" action="{dede:global name='cfg_phpurl'/}/search.php">
        <input type="hidden" name="kwtype" value="0" />
        <!-- 品牌联动选择 -->
        <select name="car_brand" id="brand_select" onchange="GetCarSeries(this.value)">
            <option value=''>请选择品牌</option>
            {dede:global name='listitem.linkage'/}
        </select>
        <!-- 车系联动选择,初始为空 -->
        <select name="car_series" id="series_select">
            <option value=''>请先选择品牌</option>
        </select>
        <input type="submit" value="搜索" />
    </form>
  2. 编写 JavaScript: 你需要一个 JS 函数来实现“选择品牌后,动态加载对应车系”的效果,将这段 JS 代码放在你模板的 <head> 标签内或底部。

    function GetCarSeries(pid) {
        // 如果pid为空,清空车系下拉框并返回
        if (pid == '') {
            document.getElementById('series_select').innerHTML = '<option value="">请先选择品牌</option>';
            return;
        }
        // 创建XMLHttpRequest对象
        var xmlhttp = null;
        if (window.XMLHttpRequest) {
            xmlhttp = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        if (xmlhttp != null) {
            // 设置回调函数
            xmlhttp.onreadystatechange = function() {
                if (xmlhttp.readyState == 4) { // 4 = "loaded"
                    if (xmlhttp.status == 200) { // 200 = "OK"
                        // 将返回的HTML设置到车系下拉框中
                        document.getElementById('series_select').innerHTML = xmlhttp.responseText;
                    } else {
                        alert("Problem retrieving data:" + xmlhttp.statusText);
                    }
                }
            };
            // 发送请求
            // 注意:这里 /plus/linkage.php 是DedeCMS的联动接口
            // &linkageid=1 是你创建的联动类别的ID,可以在后台联动类别列表看到
            // &pid= 是要查询的父级ID
            xmlhttp.open("GET", "/plus/linkage.php?linkageid=1&pid=" + pid, true);
            xmlhttp.send(null);
        }
    }
  3. 联动接口 /plus/linkage.php: 这个文件是 DedeCMS 自带的,专门用于处理联动 AJAX 请求的,它会根据你传的 linkageidpid,返回对应子级的 HTML <option> 代码。

  4. 修改搜索程序: 打开 /plus/search.php 文件,找到处理搜索参数的地方(通常是 $keyword$typeid 附近),增加对你自定义联动字段的判断。

    // 在 search.php 中找到类似这样的代码段
    if($typeid!='') {
        $typeid = GetSonIds($typeid);
    }
    // 增加你的联动字段处理逻辑
    $car_brand = isset($car_brand) && is_numeric($car_brand) ? $car_brand : '';
    $car_series = isset($car_series) && is_numeric($car_series) ? $car_series : '';
    // 然后在构建SQL查询时,将这些条件加入
    $addquery = " WHERE arc.arcrank > -1 ";
    if ($car_series != '') {
        // 如果精确搜索车系
        $addquery .= " AND arc.addtable LIKE '%dede_addonarticle%' AND (SELECT car_brand FROM dede_addonarticle WHERE aid=arc.id) = '{$car_series}' ";
    } elseif ($car_brand != '') {
        // 如果只搜索了品牌
        $addquery .= " AND arc.addtable LIKE '%dede_addonarticle%' AND (SELECT car_brand FROM dede_addonarticle WHERE aid=arc.id) LIKE '{$car_brand}%' ";
    }
    // ... 后续的SQL构建逻辑

    注意:上面的SQL是示例,实际编写时要注意SQL注入风险,并确保你的附加表名和字段名正确,更健壮的方式是使用 $dsql->SetQuery()$dsql->Execute() 来构建和执行查询。


总结与注意事项

  1. 备份数据:在进行任何二次开发,特别是修改数据库和核心文件之前,务必备份数据库和网站文件。
  2. 命名规范:字段名、enumtype 等尽量使用有意义的英文,方便后期维护。
  3. 性能考虑:频繁查询 dede_sys_enum 表可能会影响性能,对于高频访问的数据,可以考虑将联动数据缓存到数组或文件中。
  4. 版本差异:不同版本的 DedeCMS(如 5.7、5.8)可能在文件路径或函数细节上略有不同,请根据你的实际版本进行调整。
  5. 模块化开发:对于复杂的联动(如三级、四级),建议将 JS 逻辑和 PHP 逻辑封装成可复用的模块,而不是在每个地方都写一遍。

通过以上步骤,你就可以熟练地对 DedeCMS 的联动类别进行二次开发,满足各种复杂的业务需求了。

-- 展开阅读全文 --
头像
dede自适应会员中心如何实现跨设备兼容?
« 上一篇 02-27
C语言中Ctrl+C如何退出程序?
下一篇 » 02-27

相关文章

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

目录[+]