核心概念

  1. 搜索模板文件:位于 /templets/default/ 目录下,通常名为 search.htm,这是用户看到搜索结果页面的最终样式文件。
  2. 搜索处理文件:位于 /plus/ 目录下,名为 search.php,这个文件负责接收搜索关键词、查询数据库、并将数据传递给模板文件进行渲染。
  3. DedeCMS 的模板标签,如 {dede:arclist}{dede:field} 等,用于在模板中调用和显示数据。

默认情况下,search.php 只会传递给模板一些基本的数据,如关键词、结果总数、文章列表等,如果你想调用额外的数据(比如文章的作者、点击量、自定义字段等),就需要对 search.php 进行修改。

dedecms 搜索模板中调用标签
(图片来源网络,侵删)

调用默认支持的标签(无需修改 search.php

DedeCMS 默认在搜索结果页中支持一些常用标签,这些标签可以直接在 search.htm 中使用。

常用默认标签列表:

标签名 说明 示例
{dede:searchtitle} 显示搜索的关键词 <h1>搜索"{dede:searchtitle}"的结果</h1>
{dede:pagelist} 分页条 {dede:pagelist listsize='5' listitem='info,index,end,pre,next,pageno'}
{dede:pagelistitem/} 分页项(已废弃,推荐用上面的)
{dede:field.title/} 单篇文章的标题 <h2><a href="[field:arcurl/]">{dede:field.title/}</a></h2>
{dede:field.arcurl/} 单篇文章的链接 <a href="[field:arcurl/]">查看详情</a>
{dede:field.pubdate function="MyDate('Y-m-d',@me)"/} 单篇文章的发布日期 发布于:{dede:field.pubdate function='MyDate('Y-m-d',@me)'/}
{dede:field.description/} 单篇文章的摘要 [field:description/]...
{dede:field.litpic/} 单篇文章的缩略图 <img src="[field:litpic/]" alt="{dede:field.title/}" />

示例 search.htm (基础用法):

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">{dede:global.cfg_webname/} - 搜索结果</title>
</head>
<body>
    <h1>搜索 "{dede:searchtitle/}" 的结果</h1>
    <p>找到相关结果共 <strong>{dede:global.itemcount/}</strong> 条</p>
    <div class="search_results">
        {dede:list pagesize='10'}
        <div class="result-item">
            <h2><a href="[field:arcurl/]">{dede:field.title/}</a></h2>
            <p class="info">发布时间:{dede:field.pubdate function='MyDate('Y-m-d H:i:s',@me)'/} &nbsp; 点击:[field:click/]</p>
            <p class="desc">[field:description/]...</p>
            <a href="[field:arcurl/]" class="read-more">阅读全文</a>
        </div>
        {/dede:list}
    </div>
    <div class="pagination">
        {dede:pagelist listsize='5' listitem='info,index,end,pre,next,pageno'}
        {dede:pagelistitem/}
        {/dede:pagelist}
    </div>
</body>
</html>

调用非默认的标签(需要修改 search.php

假设你想在搜索结果页显示文章的 作者 (writer) 和 自定义字段 mycustomfield,由于这些信息默认没有被 search.php 捕获并传递给模板,所以你需要修改 search.php

dedecms 搜索模板中调用标签
(图片来源网络,侵删)

操作步骤:

第一步:备份 search.php

在修改任何核心文件之前,请务必备份原始文件。

第二步:修改 search.php

dedecms 搜索模板中调用标签
(图片来源网络,侵删)
  1. 找到查询数据库的核心代码段,它通常在一个 if 语句中,if($typeid > 0 || $keyword != '')
  2. 在执行查询的 mysql_query 语句之后,你需要获取结果并处理它。

示例:修改 search.php 以支持 writermycustomfield

找到类似这样的代码(大约在第 180-220 行,版本不同位置可能略有差异):

// ... 前面的代码 ...
// 执行查询
$dsql->SetQuery($query);
$dsql->Execute('al'); // 'al' 是一个别名
// ... 后面的代码 ...

在这段代码之后,在循环处理结果之前,添加以下代码来定义你需要的额外字段:

// 在 $dsql->Execute('al'); 之后添加
// 为搜索结果列表添加额外的字段
function GetSearchFields($id)
{
    global $dsql;
    $fields = array();
    // 获取文章附加表
    $addtable = $dsql->GetOne("SELECT addtable FROM `dede_arctype` WHERE id=(SELECT typeid FROM `dede_archives` WHERE id=$id)");
    if(is_array($addtable) && !empty($addtable['addtable']))
    {
        $addtable = $addtable['addtable'];
        // 从附加表中获取自定义字段
        $row = $dsql->GetOne("SELECT writer, mycustomfield FROM `$addtable` WHERE aid=$id");
        if(is_array($row))
        {
            $fields['writer'] = $row['writer'];
            $fields['mycustomfield'] = $row['mycustomfield'];
        }
    }
    return $fields;
}
// ... 后面的代码 ...

在循环输出结果的 while 循环中(大约在 while($row = $dsql->GetArray('al'))),调用这个函数并把结果合并到 $row 数组中。

找到 while 循环:

while($row = $dsql->GetArray('al'))
{
    // ... 循环内的代码 ...
}

修改为:

while($row = $dsql->GetArray('al'))
{
    // 获取附加字段
    $addfields = GetSearchFields($row['id']);
    // 将附加字段合并到主行数据中
    $row = array_merge($row, $addfields);
    // ... 循环内原有的代码,如处理标题、高亮等 ...
    // 例如处理标题高亮
    $row['title'] = $keyword ? preg_replace("/(".preg_quote($keyword).")/i", "<font color='red'>\\1</font>", $row['title']) : $row['title'];
    // ... 将 $row 赋值给模板的代码 ...
    $artlist[] = $row;
}

第三步:在 search.htm 中使用新标签

现在你可以在 search.htm 模板中直接使用 {dede:field.writer/}{dede:field.mycustomfield/} 了。

修改后的 search.htm 示例:

<div class="search_results">
    {dede:list pagesize='10'}
    <div class="result-item">
        <h2><a href="[field:arcurl/]">{dede:field.title/}</a></h2>
        <p class="info">
            作者:{dede:field.writer/} &nbsp; 
            发布时间:{dede:field.pubdate function='MyDate('Y-m-d H:i:s',@me)'/} &nbsp; 
            点击:[field:click/]
        </p>
        <!-- 自定义字段 -->
        <p class="custom-field">标签:{dede:field.mycustomfield/}</p>
        <p class="desc">[field:description/]...</p>
        <a href="[field:arcurl/]" class="read-more">阅读全文</a>
    </div>
    {/dede:list}
</div>

调用 channel 标签(搜索特定栏目)

如果你希望搜索结果只显示某个特定栏目下的内容,并且想在模板中调用该栏目的信息(如栏目名称、链接等),可以使用 {dede:channel}

方法:

  1. search.php 中传递栏目ID:你需要确保 search.php 将文章的 typeid(栏目ID)传递给了模板,默认情况下,{dede:list} 标签中的 [field:typeid/] 是可用的。
  2. search.htm 中使用 {dede:channel}:利用 [field:typeid/] 来获取当前文章所属栏目的信息。

示例 search.htm

{dede:list pagesize='10'}
<div class="result-item">
    <!-- 先获取栏目信息 -->
    {dede:channel typeid='[field:typeid/]'}
    <p class="category">栏目:<a href="[field:typelink/]">[field:typename/]</a></p>
    {/dede:channel}
    <h2><a href="[field:arcurl/]">{dede:field.title/}</a></h2>
    <p class="info">发布时间:{dede:field.pubdate function='MyDate('Y-m-d H:i:s',@me)'/}</p>
    <p class="desc">[field:description/]...</p>
</div>
{/dede:list}

总结与最佳实践

  1. 先检查默认:在修改 search.php 之前,先查阅 DedeCMS 文档或在模板中尝试使用你想要的标签,看看是否是默认支持的。
  2. 安全第一:修改 search.php 之前,务必备份,错误的修改可能导致搜索功能甚至整个网站无法正常工作。
  3. 代码清晰:在修改 search.php 时,添加清晰的注释,方便日后自己或他人维护。
  4. 权限问题:确保你的网站目录有足够的写入权限,以便修改文件。
  5. 测试:每次修改后,都要在网站前台进行充分的测试,确保搜索结果和显示都符合预期。

通过以上方法,你就可以灵活地在 DedeCMS 搜索模板中调用各种标签,实现个性化的搜索结果页。