织梦联动类别前端如何调用?

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

织梦的联动类别功能非常强大,常用于地区选择、职位分类、品牌筛选等场景,它的调用方法比普通栏目和文章要稍微复杂一些,核心在于使用 {dede:sql} 标签直接查询数据库。

织梦联动类别前端调用
(图片来源网络,侵删)

下面我将分步讲解,从最基础的调用到更复杂的联动菜单实现。


第一步:理解联动类别的数据结构

在调用之前,必须先理解织梦是如何存储联动类别数据的,它主要涉及两个数据表:

  1. #@sys_enum:存储联动类别的“顶级分类”(也就是你在后台添加的“地区”、“职位”等大项)。
  2. #@sys_enum:也存储具体的“子分类”,通过 evalue 字段和 ename 字段建立层级关系。
  • evalue:分类的值,同时也是其父分类的ID,顶级分类的 evalue 通常为0。
  • ename:分类的名称。
  • eorder:排序权重,数字越小越靠前。
  • issign:是否允许前台投稿选择,0为允许,1为不允许。
  • typeid:联动类别ID,这个非常重要,用于区分不同的联动类型(比如地区和职位是不同的typeid)。

示例数据: 假设我们有一个联动类别“地区”,其 typeid1

id ename evalue egroup eorder issign typeid
1 顶级分类 0 0 0 1
2 亚洲 1 1 0 1
3 中国 2 1 0 1
4 广东 3 1 0 1
5 北京 3 2 0 1
6 欧洲 1 2 0 1
7 法国 6 1 0 1
8 德国 6 2 0 1

从上表可以看出:

织梦联动类别前端调用
(图片来源网络,侵删)
  • ename为“亚洲”的记录,其evalue为1。
  • ename为“中国”的记录,其evalue为2,而“亚洲”的id也是2,这说明“中国”的父级是“亚洲”。
  • ename为“广东”的记录,其evalue为3,而“中国”的id也是3,这说明“广东”的父级是“中国”。

理解了这个结构,我们就可以用SQL语句来查询任意层级的数据了。


第二步:基础调用(获取所有顶级分类)

假设我们要调用一个 typeid1 的联动类别的所有顶级分类(亚洲、欧洲、北美洲...)。

在需要调用的模板文件(如 index.htm, list_article.htm 等)中,使用以下代码:

{dede:sql sql="SELECT id, ename FROM `#@__sys_enum` WHERE egroup = 'smalltypes' AND evalue = 0 AND typeid = 1 ORDER BY eorder ASC"}
    <li>
        <a href="[field:ename function='MakeOneDir(@me)'/]">[field:ename/]</a>
    </li>
{/dede:sql}

代码解析:

  • sql="...":这是SQL查询语句。
  • SELECT id, ename:选择要查询的字段,id用于后续获取子分类,ename是分类名称。
  • FROM#@__sys_enum`指定查询的数据表,#@__`是织梦表前缀的占位符。
  • WHERE egroup = 'smalltypes'重要! egroup 字段通常存储的是联动类别的英文标识(如'region', 'job'等),这个值是在你后台添加联动类别时输入的“字段名”,如果你不确定,可以去后台的“核心 -> 联动类别”里查看你添加的类别,找到对应的“字段名”。
  • AND evalue = 0:这是筛选顶级分类的关键条件,因为顶级分类的evalue都为0。
  • AND typeid = 1:指定要调用的联动类别ID,这个ID可以在后台联动类别管理页面看到。
  • ORDER BY eorder ASC:按照后台设置的排序进行升序排列。
  • [field:ename/]:循环输出每个顶级分类的名称。
  • [field:ename function='MakeOneDir(@me)'/]:这是一个函数,用于将分类名转换为拼音或英文,用作URL路径。“亚洲”会变成“ya-zhou”,你也可以直接用 [field:id/] 来拼接URL。

第三步:递归调用(实现多级联动菜单)

这是最常用也最复杂的情况,比如我们要做一个“省-市-区”三级联动菜单,由于织梦模板本身不支持递归,我们需要借助PHP和JavaScript来实现。

这里我们以一个经典的“省-市-区”三级联动菜单为例,假设联动类别的typeid1

在模板文件中放置HTML结构

<!-- 省份选择 -->
<select name="province" id="province">
    <option value="0">请选择省份</option>
    {dede:sql sql="SELECT id, ename FROM `#@__sys_enum` WHERE egroup = 'smalltypes' AND evalue = 0 AND typeid = 1 ORDER BY eorder ASC"}
        <option value="[field:id/]">[field:ename/]</option>
    {/dede:sql}
</select>
<!-- 城市选择 -->
<select name="city" id="city">
    <option value="0">请先选择省份</option>
</select>
<!-- 区县选择 -->
<select name="district" id="district">
    <option value="0">请先选择城市</option>
</select>

编写JavaScript代码处理联动逻辑

在HTML下方,加入以下 <script> 代码:

<script type="text/javascript">
    // 获取下拉框元素
    var provinceSelect = document.getElementById('province');
    var citySelect = document.getElementById('city');
    var districtSelect = document.getElementById('district');
    // 省份选择改变时,加载对应的城市
    provinceSelect.onchange = function() {
        var provinceId = this.value;
        // 清空城市和区县下拉框
        citySelect.innerHTML = '<option value="0">请选择城市</option>';
        districtSelect.innerHTML = '<option value="0">请先选择城市</option>';
        if (provinceId == 0) return;
        // 使用AJAX请求获取城市数据
        // 注意:这里需要你创建一个专门用于处理联动请求的PHP文件
        var ajax = new XMLHttpRequest();
        ajax.open('get', '/plus/get_city.php?pid=' + provinceId, true);
        ajax.send();
        ajax.onreadystatechange = function() {
            if (ajax.readyState == 4 && ajax.status == 200) {
                var data = JSON.parse(ajax.responseText);
                var html = '<option value="0">请选择城市</option>';
                for (var i = 0; i < data.length; i++) {
                    html += '<option value="' + data[i].id + '">' + data[i].ename + '</option>';
                }
                citySelect.innerHTML = html;
            }
        };
    };
    // 城市选择改变时,加载对应的区县
    citySelect.onchange = function() {
        var cityId = this.value;
        // 清空区县下拉框
        districtSelect.innerHTML = '<option value="0">请先选择城市</option>';
        if (cityId == 0) return;
        // 使用AJAX请求获取区县数据
        var ajax = new XMLHttpRequest();
        ajax.open('get', '/plus/get_district.php?pid=' + cityId, true);
        ajax.send();
        ajax.onreadystatechange = function() {
            if (ajax.readyState == 4 && ajax.status == 200) {
                var data = JSON.parse(ajax.responseText);
                var html = '<option value="0">请选择区县</option>';
                for (var i = 0; i < data.length; i++) {
                    html += '<option value="' + data[i].id + '">' + data[i].ename + '</option>';
                }
                districtSelect.innerHTML = html;
            }
        };
    };
</script>

创建AJAX请求处理文件

上面的JS代码需要两个PHP文件来响应请求:/plus/get_city.php/plus/get_district.php,这两个文件的作用是查询数据库并返回JSON格式的数据。

/plus/get_city.php (获取城市列表)

<?php
require_once(dirname(__FILE__)."/../include/common.inc.php");
// 获取省份ID
$pid = isset($_GET['pid']) ? intval($_GET['pid']) : 0;
// 查询该省份下的所有城市(即evalue等于省份ID的记录)
$sql = "SELECT id, ename FROM `#@__sys_enum` WHERE egroup = 'smalltypes' AND evalue = {$pid} AND typeid = 1 ORDER BY eorder ASC";
$dsql->SetQuery($sql);
$dsql->Execute();
$cities = array();
while ($row = $dsql->GetArray()) {
    $cities[] = $row;
}
// 输出JSON格式数据
header('Content-Type: application/json');
echo json_encode($cities);
?>

/plus/get_district.php (获取区县列表)

这个文件的代码和 get_city.php 基本一样,只是注释可以改一下。

<?php
require_once(dirname(__FILE__)."/../include/common.inc.php");
// 获取城市ID
$pid = isset($_GET['pid']) ? intval($_GET['pid']) : 0;
// 查询该城市下的所有区县
$sql = "SELECT id, ename FROM `#@__sys_enum` WHERE egroup = 'smalltypes' AND evalue = {$pid} AND typeid = 1 ORDER BY eorder ASC";
$dsql->SetQuery($sql);
$dsql->Execute();
$districts = array();
while ($row = $dsql->GetArray()) {
    $districts[] = $row;
}
// 输出JSON格式数据
header('Content-Type: application/json');
echo json_encode($districts);
?>

将这两个PHP文件上传到网站的 /plus/ 目录下,联动菜单就可以正常工作了。


第四步:高级用法(获取当前文章的联动分类值)

在文章详情页,如果文章使用了联动类别作为自定义字段,如何获取它的值呢?

假设你有一个自定义字段 shengfen (字段名),它关联了typeid为1的联动类别。

article_article.htm 模板中:

{dede:field.shengfen/} 

这会直接输出分类的evalue(3),这通常不是我们想要的。

我们需要根据evalue去查询ename

{dede:sql sql="SELECT ename FROM `#@__sys_enum` WHERE id = [field:shengfen/] AND typeid = 1"}
    当前省份:<strong>[field:ename/]</strong>
{/dede:sql}

代码解析:

  • [field:shengfen/]:获取文章自定义字段 shengfen 的值,也就是evalue
  • WHERE id = [field:shengfen/]:因为联动分类的id和其父级的evalue是相等的,所以我们可以用id来精确查找。
  • AND typeid = 1:确保查询的是正确的联动类别。
  • [field:ename/]:输出查找到的分类名称。

总结与注意事项

  1. 核心是 {dede:sql}:调用联动类别的核心方法就是通过编写SQL语句查询 #@__sys_enum 表。
  2. 关键参数
    • typeid:联动类别的ID,用于区分不同类型。
    • egroup:联动类别的“字段名”,用于区分同一ID下的不同分组(虽然通常一个typeid对应一个egroup)。
    • evalue:用于判断层级,evalue=0是顶级,evalue=父级ID是子级。
  3. 多级联动:对于多级菜单,最标准的实现方式是“HTML + JS + PHP(AJAX)”的模式,将数据库查询的压力分散到前端交互中。
  4. 性能考虑:频繁的数据库查询会影响性能,对于不常变动的联动数据(如地区),可以考虑将查询结果缓存,或者一次性加载所有数据然后在前端用JS处理。
  5. 命名规范:在后台添加联动类别时,给“字段名”起一个有意义且唯一的英文或拼音名称,方便前端调用。

希望这份详细的教程能帮助你完全掌握织梦联动类别的前端调用!

-- 展开阅读全文 --
头像
dede 获取上级栏目
« 上一篇 03-18
织梦 导航网站 模板
下一篇 » 03-19

相关文章

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

目录[+]