调用包含任意一个关键字的文章(最常用)
这是最常见的需求,比如关键字是 "织梦, PHP, 教程",我们想调用所有标题或内容中包含这三个词中至少一个的文章。

(图片来源网络,侵删)
实现步骤:
- 找到关键字:你需要知道你要查询的关键字是什么,假设这个关键字存储在某个地方,比如一个自定义栏目、一个变量,或者你直接在代码里写死。
- 编写SQL语句:核心是编写一个
SELECT语句,使用LIKE和OR来匹配。 - 使用
{dede:loop}:在模板文件中,使用loop标签来执行这个自定义的SQL查询。 - 循环输出结果:在
loop标签内部,使用常规的field标签来输出文章的标题、链接、缩略图等信息。
代码示例:
假设你的关键字是 "织梦,PHP,教程"。
{dede:loop sql='
SELECT
id,
typeid,
title,
litpic,
description,
pubdate,
click
FROM
`#@__archives`
WHERE
(title LIKE "%织梦%" OR title LIKE "%PHP%" OR title LIKE "%教程%")
AND arcrank > -1
ORDER BY
pubdate DESC
LIMIT 0, 10;
'}
<li>
<!-- [field:litpic/] 是缩略图,如果没有则不显示 -->
<a href="[field:filename/]" target="_blank">
<img src="[field:litpic/]" alt="[field:title/]" onerror="this.src='/images/defaultpic.gif'">
</a>
<h3><a href="[field:filename/]" target="_blank">[field:title/]</a></h3>
<p class="info">[field:description function="cn_substr(@me,100)"/]...</p>
<p class="time">发布时间:[field:pubdate function="MyDate('Y-m-d',@me)"/]</p>
</li>
{/dede:loop}
代码详解:
{dede:loop sql='...'}: 这是执行自定义SQL的核心标签。SELECT ... FROM#@__archives``:#@__archives是织梦数据库中文章主表的前缀,你的实际表名可能是dede_archives,使用#@__可以自动替换为你安装时设置的前缀,推荐使用。id, typeid, title, ...是你希望从数据库中获取的字段列表。
WHERE (title LIKE "%织梦%" OR title LIKE "%PHP%" OR title LIKE "%教程%"):LIKE '%关键词%'是SQL中的模糊匹配, 代表任意数量的任意字符。OR表示“或者”的关系,即满足其中一个条件即可。- 注意:这里我们只搜索了
title(标题)字段,如果你也想在(body)中搜索,需要关联附加表#@__addonarticle,这在方法三中会讲到。
AND arcrank > -1:- 这是一个非常重要的过滤条件。
arcrank是文章的审核状态。 arcrank = -1表示被删除的文章。arcrank = 0表示待审核的文章。arcrank > 0表示已审核的文章。arcrank > -1的意思是“只显示未被删除的文章”,这是一个好习惯。
- 这是一个非常重要的过滤条件。
ORDER BY pubdate DESC: 按发布日期降序排列,最新的排在前面。LIMIT 0, 10: 从第0条记录开始,只取10条,这是分页的关键,0是偏移量,10是获取数量。[field:fieldname/]: 在loop内部,用于输出SQL查询结果中对应字段的值。[field:filename/]: 文章的实际链接,比[field:id/]更准确。[field:pubdate function="MyDate('Y-m-d',@me)"/]: 对发布时间进行格式化,@me代表当前字段的原始值。
调用包含所有关键字的文章
这个需求相对少见,比如只显示标题中同时包含 "织梦" 和 "教程" 的文章。
实现步骤:
与方法一类似,只需要将SQL中的 OR 修改为 AND 即可。
代码示例:
{dede:loop sql='
SELECT
id,
typeid,
title,
litpic,
description,
pubdate
FROM
`#@__archives`
WHERE
(title LIKE "%织梦%" AND title LIKE "%教程%")
AND arcrank > -1
ORDER BY
pubdate DESC
LIMIT 0, 10;
'}
<li>
<a href="[field:filename/]" target="_blank">[field:title/]</a>
<span class="date">[field:pubdate function="MyDate('m-d',@me)"/]</span>
</li>
{/dede:loop}
和中同时搜索关键字
body)存储在附加表 #@__addonarticle 中,要同时搜索标题和内容,需要将这两个表进行 JOIN 关联查询。

(图片来源网络,侵删)
实现步骤:
- 关联主表和附加表:使用
INNER JOIN或LEFT JOIN将#@__archives和#@__addonarticle连接起来,连接条件是id = aid。 - 分别搜索两个字段:在
WHERE子句中,对title和body字段分别进行LIKE查询。
代码示例:
{dede:loop sql='
SELECT
a.id,
a.typeid,
a.title,
a.litpic,
a.description,
a.pubdate,
b.body
FROM
`#@__archives` AS a
INNER JOIN
`#@__addonarticle` AS b ON a.id = b.aid
WHERE
(a.title LIKE "%织梦%" OR a.title LIKE "%PHP%" OR a.title LIKE "%教程%")
OR (b.body LIKE "%织梦%" OR b.body LIKE "%PHP%" OR b.body LIKE "%教程%")
AND a.arcrank > -1
ORDER BY
a.pubdate DESC
LIMIT 0, 10;
'}
<li>
<a href="[field:filename/]" target="_blank">[field:title/]</a>
<p class="intro">内容片段:[field:body function='cn_substr(html2text(@me), 100)'/]...</p>
</li>
{/dede:loop}
代码详解:
FROM#@archivesAS a INNER JOIN#@addonarticleAS b ON a.id = b.aid:AS a和AS b是给两个表分别起别名,方便在查询中引用它们的字段(如a.id,b.body)。INNER JOIN ... ON a.id = b.aid表示将两个表通过ID字段关联起来。
OR (b.body LIKE ...):- 增加了对
body字段的搜索条件,并用OR与标题的搜索条件连接,意味着只要标题或内容中包含任意一个关键字,就会被检索到。
- 增加了对
[field:body function='cn_substr(html2text(@me), 100)'/]:html2text(@me): 将HTML格式的文章内容转换为纯文本。cn_substr(..., 100): 截取前100个字符。- 这个组合用于从文章正文中提取一段简短的描述。
通过栏目ID调用该栏目下文章的关键字(动态获取)
这是一个更灵活的用法,比如在栏目页,你想调用本栏目所有文章的关键字,然后根据这些关键字去全站查找相关文章。
这个逻辑稍微复杂,通常需要分两步:
- 先获取当前栏目的所有文章ID。
- 再根据这些ID去查询它们的关键字,并用这些关键字去查找其他文章。
实现步骤(示例):
假设你在列表页 (list_*.php),想调用当前栏目下所有文章的关键字,然后去查找相关文章。
{dede:loop sql='
-- 第一步:获取当前栏目ID(假设为2)下的所有文章ID,并用逗号连接起来
-- 这里我们直接写死,实际中可以通过 {dede:field name='typeid'/} 获取
SET @arc_ids = (SELECT GROUP_CONCAT(id) FROM `#@__archives` WHERE typeid = 2 AND arcrank > -1);
-- 第二步:根据获取到的ID列表,查询这些文章的关键字,并去重
-- 假设关键字在 `#@__taglist` 表中,这是一个简化的假设,实际关键字字段可能在 `#@__archives` 的 `keywords` 字段
SELECT DISTINCT keywords FROM `#@__archives` WHERE id IN (@arc_ids) AND keywords != "" LIMIT 0, 5;
-- 注意:这个查询在织梦的loop标签中直接执行可能会有问题,因为loop只返回一个结果集。
-- 更好的做法是在PHP文件中处理,然后将得到的关键字变量传递给模板。
'}
<!-- 这里得到的是单个关键字,循环遍历 -->
<a href="/plus/search.php?keyword=[field:keywords/]" target="_blank">[field:keywords/]</a>
{/dede:loop}
重要提示:方法四的实现非常复杂,涉及到多步查询和变量传递,直接在模板中用
loop实现可能不太稳定,对于这种高级需求,推荐使用PHP文件来实现,逻辑更清晰,也更可控。(图片来源网络,侵删)
总结与最佳实践
- 明确需求:首先确定你是要“任意一个关键字”还是“所有关键字”。
- 选择搜索范围:只需要搜索标题,还是标题和内容都要搜?后者需要关联附加表。
- 使用
loop:对于简单的单表查询,{dede:loop}是最直接、最高效的方式。 - 注意表前缀:始终使用
#@__代替硬编码的表名(如dede_),这样更具可移植性。 - 过滤无效文章:在
WHERE子句中加入AND arcrank > -1是一个好习惯,可以避免调用到草稿或已删除的文章。 - 性能考虑:如果网站数据量非常大,复杂的
LIKE查询可能会影响性能,可以考虑使用全文索引等数据库优化手段,但对于一般网站,loop方法的性能是足够的。
希望这些详细的解释和示例能帮助你解决问题!

