要实现这个功能,核心思路是修改搜索程序的模板和PHP处理逻辑,使其在查询时关联附加表,并将自定义字段传递给模板。
下面我将分两种情况详细讲解,一种是针对文章模型(article)的通用方法,另一种是使用更强大的 DedeV5.7 SP2 版本内置的搜索标签。
通用方法(适用于大多数DedeCMS版本,包括旧版)
这个方法需要你修改两个文件:search.php(PHP逻辑)和 search.htm(模板文件),我们以文章模型的自定义字段为例。
假设条件:
- 模型ID为 1 (文章模型)。
- 自定义字段名为
myauthor(作者) 和mydescription(简介)。 - 这些字段存储在附加表
dede_addonarticle中。
修改 search.php 文件
search.php 是处理搜索请求的核心文件,我们需要修改它,让它根据模型ID去关联对应的附加表,并取出自定义字段。
-
找到文件:在你的网站根目录下找到
search.php。 -
定位关键代码:找到处理搜索结果查询的SQL语句部分,通常在
if($typeid > 0)或if($keyword != '')的逻辑块中,搜索类似SELECT * FROM dede_archives的代码。 -
修改查询逻辑:我们需要将
SELECT * FROM dede_archives修改为JOIN查询。修改前(大概样子):
// ... 其他代码 ... $query = "SELECT * FROM `dede_archives` WHERE $typeid AND arcrank > -1 $keywordtype $keyword order by id desc"; $need = GetCacheRand($t1, $t2); $innertext = GetTemplet($cfg_basedir.$cfg_templets_dir."/search/".$cfg_needbody); // ... 其他代码 ...
修改后(关键修改): 我们需要将查询逻辑包装在一个
if条件中,判断是否是文章模型,并动态附加表名。// ... 在 search.php 中找到处理查询的部分,替换或修改如下代码 ... // 1. 获取模型ID (通常从URL参数typeid来) $typeid = isset($typeid) ? intval($typeid) : 0; // 2. 获取附加表名 (这里以文章模型为例) $addtable = ''; if($typeid > 0) { $typeRow = $dsql->GetOne("SELECT addtable FROM `dede_arctype` WHERE id='$typeid'"); if(is_array($typeRow)) { $addtable = $typeRow['addtable']; } } // 3. 修改核心查询语句 $query = "SELECT a.*, t.* FROM `dede_archives` a "; if($addtable != '') { $query .= " LEFT JOIN `$addtable` t ON a.id = t.aid "; } $query .= " WHERE a.arcrank > -1 "; // 添加typeid条件 if($typeid > 0) { $query .= " AND a.typeid = '$typeid' "; } // 添加关键词搜索条件 (这里只搜索标题和正文,你也可以加入自定义字段) $keyword = filterSearch($keyword); if($keyword != ''){ $query .= " AND (a.title LIKE '%$keyword%' OR a.description LIKE '%$keyword%'"; // --- 关键:加入自定义字段的搜索 --- if($addtable == 'dede_addonarticle') { // 判断是否是文章附加表 $query .= " OR t.myauthor LIKE '%$keyword%' OR t.mydescription LIKE '%$keyword%'"; } // --- 如果有其他模型,可以继续添加 else if --- $query .= ") "; } $query .= " ORDER BY a.id DESC"; // ... 后续代码保持不变 ...代码解释:
- 我们将
SELECT *改为SELECT a.*, t.*,这样既能获取主表字段(用a.前缀),也能获取附加表字段(用t.前缀)。 - 通过
LEFT JOIN关联了主表dede_archives(别名为a) 和附加表 (别名为t),关联条件是a.id = t.aid。 - 在搜索条件中,我们加入了自定义字段
t.myauthor和t.mydescription的搜索。
- 我们将
修改搜索模板 search.htm
现在PHP已经把自定义字段的数据查询出来了,我们只需要在模板中像调用普通字段一样调用它们即可。
-
找到文件:
/templets/default/search.htm(或者你自定义的搜索模板路径)。 -
在循环列表中调用字段:找到
{dede:list}或{dedarclist}标签,在里面直接调用。示例代码:
<div class="search_result"> <h3>搜索结果</h3> <ul> {dede:list pagesize='10'} <li> <a href="[field:arcurl/]">[field:title/]</a> <span class="info">([field:pubdate function="MyDate('Y-m-d',@me)"/])</span> <!-- 调用自定义字段 --> <div class="custom_field"> <p><strong>作者:</strong>[field:myauthor/]</p> <p><strong>简介:</strong>[field:mydescription/]</p> </div> <div class="intro"> [field:description function='cn_substr(@me, 200)'/]... </div> </li> {/dede:list} </ul> <!-- 分页标签 --> <div class="page_nav"> {dede:pagelist listsize='4' listitem='info,index,end,pre,next,pageno'} {/dede:pagelist} </div> </div>
重要提示:
- 字段名:
[field:myauthor/]中的myauthor必须和你后台添加的自定义字段名完全一致。 - 前缀:在模板中调用附加表字段时,通常不需要加表前缀(如
t.),Dede的列表标签会自动处理。 - 安全过滤:如果自定义字段是用户可以输入的(比如简介),最好加上
htmlspecialchars函数防止XSS攻击,[field:mydescription function='htmlspecialchars(@me)'/]。
使用 DedeV5.7 SP2 内置的搜索标签(推荐)
如果你的 DedeCMS 版本是 7 SP2 或更高版本,系统已经内置了更强大的搜索标签,可以非常方便地调用自定义字段,而无需修改 search.php。
在模板中使用 {dede:global name='keyword' function='RemoveXSS(@me)'/} 获取搜索关键词
使用 {dede:list} 标签并指定附加表
这是最关键的一步,在 {dede:list} 标签中,通过 addtable 属性指定要查询的附加表。
示例代码 search.htm:
<div class="search_result">
<h3>搜索关键词:<strong>{dede:global name='keyword' function='RemoveXSS(@me)'/}</strong> 的结果</h3>
<ul>
{dede:list
pagesize='10'
titlelen='50'
infolen='200'
addtable='dede_addonarticle' <!-- 关键:指定附加表名 -->
keyword='{dede:global name='keyword' function='RemoveXSS(@me)'/}' <!-- 关键:传入搜索关键词 -->
}
<li>
<a href="[field:arcurl/]" target="_blank">[field:title/]</a>
<span class="info">([field:pubdate function="MyDate('Y-m-d',@me)"/])</span>
<!-- 直接调用自定义字段 -->
<div class="custom_field">
<p><strong>作者:</strong>[field:myauthor/]</p>
<p><strong>简介:</strong>[field:mydescription function='cn_strim(@me, 100)'/]</p>
</div>
<div class="intro">
[field:description function='cn_substr(@me, 200)'/]...
</div>
</li>
{/dede:list}
</ul>
<!-- 分页标签 -->
<div class="page_nav">
{dede:pagelist listsize='4' listitem='info,index,end,pre,next,pageno'}
{/dede:pagelist}
</div>
</div>
代码解释:
addtable='dede_addonarticle':告诉列表标签要去dede_addonarticle这张表里查找字段。keyword='...':将全局搜索关键词传递给列表标签,使其能进行全文检索。- 这种方法的优势是纯模板操作,非常安全,且不会因为升级DedeCMS而丢失修改(只要不覆盖模板文件)。
总结与对比
| 特性 | 方法一 (修改PHP) | 方法二 (内置标签) |
|---|---|---|
| 适用版本 | 所有版本 | DedeCMS 5.7 SP2 及以上 |
| 修改文件 | search.php + search.htm |
仅 search.htm |
| 复杂度 | 较高,需要懂SQL和PHP | 非常低,只需修改模板 |
| 灵活性 | 极高,可以写任意复杂的查询逻辑 | 较高,但受限于标签功能 |
| 安全性 | 较低,修改核心文件有风险 | 高,不触碰核心程序 |
| 推荐度 | 仅在旧版或不支持新版标签时使用 | 强烈推荐,是首选方案 |
给你的建议:
- 首先检查你的DedeCMS版本,如果是 5.7 SP2 或更新,请毫不犹豫地使用方法二。
- 如果是旧版本,或者方法二无法满足你的特殊需求(比如需要同时搜索多个模型),再考虑使用方法一。
- 在操作前,务必备份你将要修改的文件(
search.php和search.htm),以防出错。
希望这个详细的教程能帮助你解决问题!
