dede如何调用三级栏目内的文章?

99ANYc3cd6
预计阅读时长 17 分钟
位置: 首页 DEDE建站 正文

核心思路

核心思路是利用 DedeCMS 的 SQL 查询功能,通过 dede_arctype 表和 dede_archives 表的关联,精准地定位到三级栏目及其所有子栏目(即三级栏目本身)的文章。

dede 调用三级栏目内的文章
(图片来源网络,侵删)

关键数据表:

  • {dede_arctype}: 存储所有栏目信息。
  • {dede_archives}: 存储所有文章的基本信息(标题、ID、发布时间等)。
  • {dede_addonarticle}: 存储文章正文内容(如果使用的是文章模型)。

关键字段:

  • typeid: 栏目的ID。
  • reid: 栏目的父级栏目ID。
  • topid: 栏目的顶级栏目ID。
  • typedir: 栏目的目录。

使用 {dede:sql} 标签(最灵活、最推荐)

这是最直接、最灵活的方法,可以直接在模板中写 SQL 语句来获取数据。

场景1:调用某个特定三级栏目内的文章

假设您已经知道这个三级栏目的ID是 15

dede 调用三级栏目内的文章
(图片来源网络,侵删)

模板代码:

{dede:sql sql="SELECT a.*,b.body FROM `dede_archives` a LEFT JOIN `dede_addonarticle` b ON a.id = b.aid WHERE a.typeid = 15 ORDER BY a.pubdate DESC LIMIT 10"}
    <li>
        <a href="[field:arcurl/]">[field:title/]</a>
        <span>[field:pubdate function="MyDate('Y-m-d',@me)"/]</span>
    </li>
{/dede:sql}

代码解释:

  • SELECT a.*,b.body: 从 dede_archives (别名为 a) 表选择所有字段,并从 dede_addonarticle (别名为 b) 表中选择 body 字段(文章内容)。
  • LEFT JOIN ... ON a.id = b.aid: 将文章表和文章内容表通过文章ID (aid) 关联起来。
  • WHERE a.typeid = 15: 这是关键,指定只查询栏目ID为 15 的文章。
  • ORDER BY a.pubdate DESC: 按发布时间降序排列,最新的在前。
  • LIMIT 10: 限制只调用10篇文章。
  • [field:arcurl/]: 获取文章链接。
  • [field:title/]: 获取文章标题。
  • [field:pubdate ...]: 对发布时间进行格式化。

场景2:调用某个二级栏目下所有三级栏目的文章

假设您要调用二级栏目ID为 5 下的所有三级栏目(比如ID为 15, 16, 17)的文章。

模板代码:

dede 调用三级栏目内的文章
(图片来源网络,侵删)
{dede:sql sql="SELECT a.*,b.body FROM `dede_archives` a LEFT JOIN `dede_addonarticle` b ON a.id = b.aid WHERE a.typeid IN (15, 16, 17) ORDER BY a.pubdate DESC LIMIT 10"}
    <li>
        <a href="[field:arcurl/]">[field:title/]</a>
        <span>[field:pubdate function="MyDate('Y-m-d',@me)"/]</span>
    </li>
{/dede:sql}

代码解释:

  • WHERE a.typeid IN (15, 16, 17): 使用 IN 关键字,指定查询多个栏目ID的文章。

如何动态获取二级栏目下的所有三级栏目ID? 您不能在模板中直接写死ID,需要先通过PHP获取,但Dede模板的灵活性有限,一个更优雅的解决方案是使用自定义函数。

(进阶)使用自定义函数动态获取ID

  1. /include/extend.func.php 文件中添加以下函数:

    /**
     * 获取指定父栏目下的所有子栏目ID
     * @param int $pid 父栏目ID
     * @return string 子栏目ID,用逗号隔开,如 '15,16,17'
     */
    function GetSonTypeId($pid) {
        global $dsql;
        $typeid = '';
        $query = "SELECT id FROM `dede_arctype` WHERE reid = $pid";
        $dsql->Execute('me', $query);
        while ($row = $dsql->GetArray('me')) {
            $typeid .= $row['id'] . ',';
        }
        // 去掉最后一个逗号
        return trim($typeid, ',');
    }
  2. 在模板中调用:

    {dede:sql sql="SELECT a.*,b.body FROM `dede_archives` a LEFT JOIN `dede_addonarticle` b ON a.id = b.aid WHERE a.typeid IN (~GetSonTypeId(5)~) ORDER BY a.pubdate DESC LIMIT 10"}
        <li>
            <a href="[field:arcurl/]">[field:title/]</a>
            <span>[field:pubdate function="MyDate('Y-m-d',@me)"/]</span>
        </li>
    {/dede:sql}
    • ~GetSonTypeId(5)~ 是Dede调用自定义函数的语法,它会执行 GetSonTypeId(5) 并将返回值(如 '15,16,17')替换到SQL语句中。

使用嵌套的 {dede:channel}{dede:arclist}

这种方法比较传统,通过循环调用实现,逻辑清晰但代码量稍多。

模板代码:

{dede:channel type='son' typeid='5'}  <!-- 假设5是二级栏目的ID -->
    {dede:arclist titlelen='30' row='10' orderby='pubdate'}
        <li>
            <!-- [field:typename/] 可以显示当前是哪个三级栏目 -->
            <span>[field:typename/]:</span>
            <a href="[field:arcurl/]">[field:title/]</a>
        </li>
    {/dede:arclist}
{/dede:channel}

代码解释:

  1. {dede:channel type='son' typeid='5'}:
    • typeid='5': 指定父栏目ID为 5 的二级栏目。
    • type='son': 获取它的所有直接子栏目(即三级栏目)。
  2. {dede:arclist ...}: 在 {dede:channel} 循环内部,{dede:arclist} 会自动循环遍历每一个子栏目(三级栏目),并调用该栏目下的文章。

优点: 代码直观,不需要写SQL。 缺点: 如果三级栏目很多,会产生多次数据库查询,性能上不如 {dede:sql} 方法,且无法一次性混合所有三级栏目的文章进行排序(比如按时间倒序)。


修改PHP源码(不推荐,有风险)

这是最根本的解决方法,通过修改DedeCMS的核心文件,让 arclist 标签支持 typeid 为三级栏目ID,但强烈不建议普通用户操作,因为升级系统后修改会丢失,且容易出错。

修改步骤(仅作了解):

  1. 找到文件 /include/taglib/arclist.lib.php
  2. 找到 $typeid = trim(preg_replace('/[^0-9,]/', '', $typeid)); 这类代码。
  3. 在它后面添加逻辑,判断 $typeid 是否是三级栏目,如果是,则获取其所有同级栏目的ID,再进行后续查询。
  4. 这个逻辑比较复杂,需要理解Dede的栏目结构查询。

除非您是开发者,否则请优先选择 方法一


总结与建议

方法 优点 缺点 推荐场景
{dede:sql} 性能最好,最灵活,可精确控制查询逻辑 需要编写SQL语句,对新手有一定门槛 强烈推荐,适用于绝大多数三级栏目调用场景,尤其是需要复杂查询或排序时。
嵌套标签 代码直观,易于理解 性能稍差,代码量大,排序不灵活 栏目数量极少,且不需要复杂排序,且不想写SQL时使用。
修改源码 一劳永逸,从根本上解决问题 风险极高,升级会失效,易出错 仅适用于高级开发者,有特殊需求且无法通过模板实现时。

对于绝大多数用户来说,使用 {dede:sql} 标签是最佳选择,特别是结合自定义函数 GetSonTypeId(),可以非常优雅和高效地实现“调用某个二级栏目下所有三级栏目”的需求。

-- 展开阅读全文 --
头像
织梦CMS文章摘要如何彻底删除?
« 上一篇 2025-12-31
c语言中doublegamma
下一篇 » 2025-12-31

相关文章

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