这是一个非常常见的需求,因为默认情况下,搜索页(search.php)的模板文件 search.htm 中是不支持 {dede:type} 标签的。{dede:type} 标签主要用于在列表页、内容页等根据栏目ID获取栏目信息,而搜索页是动态生成的,其上下文环境与普通栏目页不同,所以系统默认没有加载这个标签所需的函数库。

(图片来源网络,侵删)
核心问题分析
要使 {dede:type} 在搜索页生效,我们需要做两件事:
- 引入函数库:在搜索页模板中引入处理
{dede:type}标签所需的函数文件。 - 传递栏目ID:确保在搜索页的循环中,有可用的栏目ID变量传递给
{dede:type}
直接修改搜索页模板(推荐,简单直接)
这是最简单快捷的方法,只需要修改 search.htm 模板文件即可。
第1步:引入 typeunit.helper.php 文件
在 search.htm 文件的头部, {dede:global name='keyword'/} 等全局标签之后,{dede:list} 标签之前,引入以下代码:
{dede:include filename="head.htm"/}
<!-- 引入处理 type 标签的文件 -->
{dede:php}
require_once(DEDEINC."/typeunit.helper.php");
{/dede:php}
代码解释:

(图片来源网络,侵删)
require_once(DEDEINC."/typeunit.helper.php");这行代码告诉PHP去加载typeunit.helper.php这个文件,这个文件包含了{dede:type}标签解析的核心逻辑GetTypeUrl()等函数。DEDEINC是织梦CMS常量,代表include目录。
第2步:在搜索结果循环中使用 {dede:type}
现在你可以在搜索结果的循环标签 {dede:datalist} 中正常使用 {dede:type} 了。
假设你的搜索结果循环结构如下:
<div class="search_result">
<h2>搜索结果</h2>
<ul>
{dede:datalist}
<li>
<h3><a href="[field:arcurl/]">[field:title/]</a></h3>
<p>[field:description function='cn_substr(@me,100)'/]...</p>
<div class="info">
发布时间:[field:pubdate function="MyDate('Y-m-d',@me)"/]
来源:[field:source/]
作者:[field:writer/]
</div>
</li>
{/dede:datalist}
</ul>
</div>
你可以在每个搜索结果项中,通过 {dede:type} 来获取该文章所属栏目的信息,比如栏目名称和栏目链接。
修改后的示例:
(图片来源网络,侵删)
<div class="search_result">
<h2>搜索结果</h2>
<ul>
{dede:datalist}
<li>
<h3>
<!-- 获取当前文章的栏目ID,并使用type标签获取栏目链接 -->
{dede:type}[field:id/]{/dede:type}
<a href="[field:arcurl/]">[field:title/]</a>
</h3>
<p>[field:description function='cn_substr(@me,100)'/]...</p>
<div class="info">
发布时间:[field:pubdate function="MyDate('Y-m-d',@me)"/]
来源:[field:source/]
作者:[field:writer/]
<!-- 获取栏目名称 -->
所属栏目:{dede:type}[field:id/]{/dede:type}
</div>
</li>
{/dede:datalist}
</ul>
</div>
更简洁的写法(推荐):
你可以把 {dede:type} 和 <a> 标签结合使用,让用户点击标题时也能进入栏目。
<h3>
<a href="{dede:type}[field:id/]{/dede:type}">
[field:title/]
</a>
</h3>
<div class="info">
所属栏目:<a href="{dede:type}[field:id/]{/dede:type}">{dede:type}[field:id/]{/dede:type}</a>
</div>
工作原理:
{dede:datalist} 循环每处理一条搜索结果时,[field:id/] 会代表当前这条文章的栏目ID。
{dede:type} 标签会捕获这个ID,并调用 typeunit.helper.php 中的函数去数据库中查询对应的栏目信息。
{dede:type} 标签对会返回该栏目的链接地址(当它被 <a> 标签包含时)或栏目名称(当它被其他标签包含时,或单独使用时)。
修改PHP源文件(不推荐,升级会失效)
这种方法通过修改 search.php 文件,使其像普通栏目页一样加载标签解析环境,虽然一劳永逸,但会破坏文件结构,并且在下次织梦CMS升级时,你的修改会被覆盖,需要重新修改。
警告:此方法仅适用于对PHP和织梦有一定了解的开发者,且不推荐在正式生产环境中使用。
操作步骤:
- 打开
/plus/search.php 文件。
- 在文件中找到类似这样的代码(通常在获取分页信息之后):
$t1 = ExecTime();
//获得一个列表
$dlist = new DataList($dsql);
$dlist->SetTemplate($tempfile);
$dlist->SetSource($query);
$dlist->Display();
- 在
$dlist->SetTemplate($tempfile); 这一行之前,添加以下代码:// 加载标签库,使type标签可用
require_once(DEDEINC.'/arc.partview.class.php');
$GLOBALS['artlist'] = new PartView($typeid);
$GLOBALS['artlist']->SetTemplet($tempfile);
$GLOBALS['artlist']->Display();
exit();
- 保存文件。
这种方法为什么“不好”?
- 破坏了原有的逻辑:
search.php 的核心是 DataList 类,而这段代码引入了 PartView 类,并提前 exit() 退出了程序,完全绕过了原有的搜索结果处理逻辑。
- 升级风险:一旦你升级织梦CMS,这个文件会被还原,功能就会失效。
- 可能引发冲突:修改核心文件有时会与其他插件或自定义功能产生意想不到的冲突。
总结与最佳实践
方法
优点
缺点
推荐度
修改模板
安全、简单、可逆,不破坏核心文件,升级不受影响。
每个主题都需要手动修改一次。
⭐⭐⭐⭐⭐ (强烈推荐)
修改PHP
修改一次,所有主题都生效。
破坏核心文件,升级后失效,有潜在风险。
⭐ (仅用于特殊需求或测试)
对于绝大多数用户和开发者来说,方法一是唯一正确的选择,它遵循了模板分离的原则,将表现层的修改与核心业务逻辑的修改分离开来,是最规范、最安全的做法。
请根据你的需求选择合适的方法,并务必在修改前备份好你的文件。
现在你可以在搜索结果的循环标签 {dede:datalist} 中正常使用 {dede:type} 了。
假设你的搜索结果循环结构如下:
<div class="search_result">
<h2>搜索结果</h2>
<ul>
{dede:datalist}
<li>
<h3><a href="[field:arcurl/]">[field:title/]</a></h3>
<p>[field:description function='cn_substr(@me,100)'/]...</p>
<div class="info">
发布时间:[field:pubdate function="MyDate('Y-m-d',@me)"/]
来源:[field:source/]
作者:[field:writer/]
</div>
</li>
{/dede:datalist}
</ul>
</div>
你可以在每个搜索结果项中,通过 {dede:type} 来获取该文章所属栏目的信息,比如栏目名称和栏目链接。
修改后的示例:

(图片来源网络,侵删)
<div class="search_result">
<h2>搜索结果</h2>
<ul>
{dede:datalist}
<li>
<h3>
<!-- 获取当前文章的栏目ID,并使用type标签获取栏目链接 -->
{dede:type}[field:id/]{/dede:type}
<a href="[field:arcurl/]">[field:title/]</a>
</h3>
<p>[field:description function='cn_substr(@me,100)'/]...</p>
<div class="info">
发布时间:[field:pubdate function="MyDate('Y-m-d',@me)"/]
来源:[field:source/]
作者:[field:writer/]
<!-- 获取栏目名称 -->
所属栏目:{dede:type}[field:id/]{/dede:type}
</div>
</li>
{/dede:datalist}
</ul>
</div>
更简洁的写法(推荐):
你可以把 {dede:type} 和 <a> 标签结合使用,让用户点击标题时也能进入栏目。
<h3>
<a href="{dede:type}[field:id/]{/dede:type}">
[field:title/]
</a>
</h3>
<div class="info">
所属栏目:<a href="{dede:type}[field:id/]{/dede:type}">{dede:type}[field:id/]{/dede:type}</a>
</div>
工作原理:
{dede:datalist}循环每处理一条搜索结果时,[field:id/]会代表当前这条文章的栏目ID。{dede:type}标签会捕获这个ID,并调用typeunit.helper.php中的函数去数据库中查询对应的栏目信息。{dede:type}标签对会返回该栏目的链接地址(当它被<a>标签包含时)或栏目名称(当它被其他标签包含时,或单独使用时)。
修改PHP源文件(不推荐,升级会失效)
这种方法通过修改 search.php 文件,使其像普通栏目页一样加载标签解析环境,虽然一劳永逸,但会破坏文件结构,并且在下次织梦CMS升级时,你的修改会被覆盖,需要重新修改。
警告:此方法仅适用于对PHP和织梦有一定了解的开发者,且不推荐在正式生产环境中使用。
操作步骤:
- 打开
/plus/search.php文件。 - 在文件中找到类似这样的代码(通常在获取分页信息之后):
$t1 = ExecTime(); //获得一个列表 $dlist = new DataList($dsql); $dlist->SetTemplate($tempfile); $dlist->SetSource($query); $dlist->Display();
- 在
$dlist->SetTemplate($tempfile);这一行之前,添加以下代码:// 加载标签库,使type标签可用 require_once(DEDEINC.'/arc.partview.class.php'); $GLOBALS['artlist'] = new PartView($typeid); $GLOBALS['artlist']->SetTemplet($tempfile); $GLOBALS['artlist']->Display(); exit();
- 保存文件。
这种方法为什么“不好”?
- 破坏了原有的逻辑:
search.php的核心是DataList类,而这段代码引入了PartView类,并提前exit()退出了程序,完全绕过了原有的搜索结果处理逻辑。 - 升级风险:一旦你升级织梦CMS,这个文件会被还原,功能就会失效。
- 可能引发冲突:修改核心文件有时会与其他插件或自定义功能产生意想不到的冲突。
总结与最佳实践
| 方法 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|
| 修改模板 | 安全、简单、可逆,不破坏核心文件,升级不受影响。 | 每个主题都需要手动修改一次。 | ⭐⭐⭐⭐⭐ (强烈推荐) |
| 修改PHP | 修改一次,所有主题都生效。 | 破坏核心文件,升级后失效,有潜在风险。 | ⭐ (仅用于特殊需求或测试) |
对于绝大多数用户和开发者来说,方法一是唯一正确的选择,它遵循了模板分离的原则,将表现层的修改与核心业务逻辑的修改分离开来,是最规范、最安全的做法。
请根据你的需求选择合适的方法,并务必在修改前备份好你的文件。
