使用自定义SQL + channelartlist 标签(最推荐,最灵活)
这种方法的核心思想是:先通过 channelartlist 标签获取所有同级栏目,然后在循环中,对每个同级栏目执行一个自定义SQL查询,获取其下的推荐文章。

优点:
- 性能高:使用原生SQL查询,比嵌套
arclist标签效率更高。 - 功能强大:可以精确控制查询条件,如文章状态、推荐级别、时间范围等。
- 代码整洁:逻辑清晰,易于维护。
实现步骤:
-
确定你的文章推荐字段 在进行操作前,请确保你的文章数据表中有一个字段用于标记“推荐文章”,通常是
arctype表中的isdefault字段(值为1时表示推荐),或者自定义一个字段,flag(包含 'c' 或 'recommend' 等字符),这里我们以最常用的isdefault字段为例。 -
在模板中添加代码 打开你需要显示同级推荐文章的模板文件(通常是
article_article.htm)。
(图片来源网络,侵删) -
将以下代码粘贴到合适的位置下方):
<h3 class="same-level-title">推荐阅读</h3>
<ul class="same-level-list">
{dede:channelartlist typeid='0'}
{dede:sql sql='
SELECT
a.id,
a.title,
a.litpic,
a.pubdate,
t.typename,
t.id AS typeid
FROM
dede_archives AS a
LEFT JOIN
dede_arctype AS t ON a.typeid = t.id
WHERE
a.typeid IN ([!--id--]) -- 这里会自动替换为当前同级栏目的ID
AND a.isdefault = 1 -- 核心条件:只查询推荐的文章
AND a.arcrank >= 0 -- 只显示已审核的文章
ORDER BY
a.pubdate DESC
LIMIT 0, 5 -- 限制显示5条,你可以根据需要修改
'}
<li>
<a href="[field:arcurl/]" title="[field:title/]">
<img src="[field:litpic/]" alt="[field:title/]">
<span>[field:title/]</span>
</a>
</li>
{/dede:sql}
{/dede:channelartlist}
</ul>
代码解析:
-
{dede:channelartlist typeid='0'}typeid='0'表示获取所有顶级栏目,如果你的页面在二级栏目下,并且想获取同属于一个父栏目的兄弟栏目,你需要将typeid设置为父栏目的ID,当前栏目ID是 5,它的父栏目ID是 3,那么这里就写typeid='3'。- 这个标签会循环遍历所有符合条件的同级栏目。
-
{dede:sql sql='...'}
(图片来源网络,侵删)- 这是在
channelartlist循环内部执行的SQL语句。 a.typeid IN ([!--id--]):[!--id--]是一个特殊的占位符,DedeCMS会自动将其替换为当前正在循环的栏目的ID,因为channelartlist循环的是同级栏目,所以这个SQL会为每个同级栏目执行一次,查询该栏目下的推荐文章。AND a.isdefault = 1:这是筛选“推荐文章”的关键,如果你的推荐字段是flag并且包含 'c',那么条件应该写成AND (a.flag LIKE '%c%')。LIMIT 0, 5:限制每条SQL查询只返回5条结果,你可以调整这个数字来控制显示数量。
- 这是在
-
[field:arcurl/],[field:title/],[field:litpic/]这些是SQL查询结果中的字段,用于输出文章链接、标题和缩略图。
使用嵌套 arclist 标签(简单,但性能稍差)
如果你的同级栏目数量不多,或者对性能要求不高,可以使用嵌套标签的方法,这种方法更直观,但DedeCMS在解析多层嵌套标签时会有一定的性能开销。
实现步骤:
-
同样,先确定你的推荐字段(如
isdefault=1)。 -
在模板中添加以下代码:
<h3 class="same-level-title">推荐阅读</h3>
<ul class="same-level-list">
{dede:channelartlist typeid='0'}
{dede:arclist flag='c' typeid='[!--id--]' row='5' titlelen='30'}
<li>
<a href="[field:arcurl/]" title="[field:title/]">
<img src="[field:litpic/]" alt="[field:title/]">
<span>[field:title/]</span>
</a>
</li>
{/dede:arclist}
{/dede:channelartlist}
</ul>
代码解析:
{dede:channelartlist}:和第一种方法一样,用于获取同级栏目列表。{dede:arclist ...}:在channelartlist的循环内部,使用arclist标签来获取当前栏目的推荐文章。typeid='[!--id--]':指定当前同级栏目的ID。flag='c':这是最关键的部分。flag='c'的作用等同于isdefault=1,是DedeCMS内置的推荐文章标识,如果你的推荐方式不同,请修改此参数。row='5':控制每个栏目下显示5条推荐文章。titlelen='30'长度截取为30个字符。
修改PHP文件(最彻底,但有一定风险)
这种方法需要修改DedeCMS的核心文件,可以实现将同级推荐文章作为变量直接传递给模板,优点是模板调用非常简洁,缺点是修改核心文件,升级DedeCMS时可能会被覆盖,需要重新修改。
警告: 此方法需要你具备一定的PHP和DedeCMS知识,操作前请务必备份文件!
实现步骤(以修改 arc.archives.class.php 为例):
- 找到文件:
/include/arc.archives.class.php - 定位函数:找到
ParseTemplet()函数。 - 添加自定义逻辑:在函数内,在
$this->ParseTemplets();这行代码之前,添加获取同级推荐文章的代码。
// 在 arc.archives.class.php 的 ParseTemplet() 函数中添加
// 获取当前栏目的信息
$channelType = $this->ChannelInfos;
$parentid = $channelType['topid']; // 获取当前栏目的顶级父ID,如果是一级栏目,则topid就是自己
// 获取所有顶级栏目(即同级栏目的父级)
$dsql->SetQuery("SELECT id, typename FROM `dede_arctype` WHERE id = {$parentid}");
$dsql->Execute('t');
$parentType = $dsql->GetArray('t');
// 获取所有顶级栏目下的子栏目(即同级栏目)
$dsql->SetQuery("SELECT id, typename FROM `dede_arctype` WHERE topid = {$parentid}");
$dsql->Execute('t');
$brotherTypes = $dsql->GetArray('t');
// 构建同级栏目ID字符串
$brotherIds = '';
if(is_array($brotherTypes)){
foreach($brotherTypes as $btype){
$brotherIds .= $btype['id'] . ',';
}
}
$brotherIds = trim($brotherIds, ',');
// 查询这些同级栏目下的推荐文章
$recommendQuery = "SELECT a.id, a.title, a.litpic, a.pubdate FROM dede_archives a
LEFT JOIN dede_arctype t ON a.typeid = t.id
WHERE a.typeid IN ({$brotherIds}) AND a.isdefault = 1 AND a.arcrank >= 0
ORDER BY a.pubdate DESC LIMIT 0, 6";
$dsql->SetQuery($recommendQuery);
$dsql->Execute('r');
$recommendArticles = array();
while($row = $dsql->GetArray('r')){
$recommendArticles[] = $row;
}
// 将结果分配给模板变量
$this->Fields['same_level_recommend'] = $recommendArticles;
// ... 继续执行原有的模板解析逻辑
- 在模板中调用: 修改你的模板文件,直接使用循环输出变量。
<h3 class="same-level-title">推荐阅读</h3>
<ul class="same-level-list">
{dede:getdata name='same_level_recommend'}
<li>
<a href="[field:id runphp='yes'] $id = @me; @me = GetOneArchive($id); @me = $id['arcurl']; [/field:id]" title="[field:title/]">
<img src="[field:litpic/]" alt="[field:title/]">
<span>[field:title/]</span>
</a>
</li>
{/dede:getdata}
</ul>
注意:模板中的调用方式可能因PHP代码的具体实现而略有不同,{dede:getdata} 是一个通用的数据循环标签。
总结与建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 自定义SQL | 性能好、灵活、代码整洁 | 需要写SQL,对新手稍有门槛 | 强烈推荐,绝大多数情况下首选 |
| 嵌套标签 | 简单直观,无需修改文件 | 性能稍差,标签嵌套复杂时解析慢 | 同级栏目少,对性能要求不高的简单网站 |
| 修改PHP | 模板调用最简洁,功能集成度高 | 修改核心文件,有升级风险,不易维护 | 对性能和模板简洁性有极致要求,且不介意维护的复杂项目 |
对于绝大多数用户来说,强烈推荐使用方法一,它在性能、灵活性和易用性之间取得了最好的平衡。
