使用织梦自带搜索(最简单,但有限制)
织梦默认的搜索是全站搜索,但我们可以通过一个“小技巧”来限制它只搜索当前栏目。

实现原理:
在搜索页面的URL中,通过一个隐藏的表单字段(如 typeid)来传递当前栏目的ID,然后修改搜索程序,让它只搜索指定栏目ID下的内容。
操作步骤:
-
在列表页或内容页添加搜索框 在您需要显示搜索框的模板文件中(
list_article.htm或article_article.htm),找到您想放置搜索框的位置,添加如下代码:<form name="formsearch" action="{dede:global.cfg_cmspath/}/search.php" method="get"> <input type="hidden" name="typeid" value="{dede:field.id/}" /> <div class="form-search"> <input type="text" name="q" class="search-keyword" placeholder="搜索..." /> <button type="submit" class="search-submit">搜索</button> </div> </form>{dede:field.id/}:这是关键,它会自动获取当前栏目的ID,并作为隐藏字段typeid的值传递给搜索程序。
-
修改搜索程序文件
search.php这是实现限制搜索的核心步骤,您需要修改织梦根目录下的search.php文件。
(图片来源网络,侵删)- 找到处理搜索逻辑的代码:在
search.php文件中,找到大约在第35行左右的if($typeid > 0)判断块。 - 修改SQL查询:将该块代码修改如下:
// 找到类似下面这样的代码块 /* if($typeid > 0) { $typeid = GetSonIds($typeid); $addsql .= " And arc.typeid in({$typeid})"; } */ // 将其修改为以下代码(如果已经存在,只需确保逻辑正确) if (!empty($typeid)) // 使用 !empty() 更严谨 { // 获取当前栏目及其所有子栏目的ID $typeid = GetSonIds($typeid); if ($typeid) { // 将栏目ID限制条件添加到SQL查询中 $addsql .= " And arc.typeid in({$typeid})"; } }- 解释:
!empty($typeid):检查是否传入了typeid参数。GetSonIds($typeid):这是一个织梦内置函数,非常重要!它会获取当前栏目ID及其所有子栏目的ID列表(1,3,4,5),确保搜索范围包含子栏目。$addsql .= " And arc.typeid in({$typeid})";:这句代码将栏目ID的限制条件追加到最终的SQL查询语句中,从而实现只搜索指定栏目。
- 找到处理搜索逻辑的代码:在
-
清空缓存并测试 修改完文件后,登录织梦后台,点击“生成” -> “一键更新站点缓存”,然后刷新您的页面,在搜索框中输入关键词进行测试。
使用AJAX无刷新搜索(用户体验好)
如果不想刷新页面就能看到搜索结果,可以使用AJAX技术。
实现原理: 与方法一类似,但搜索请求通过JavaScript发送到后台,后台处理完数据后,再将结果以HTML片段的形式返回,最后由JavaScript动态插入到页面中。
操作步骤:
-
创建一个专门处理AJAX搜索的文件 在您的模板目录(
/templets/default/)下新建一个文件,命名为ajax_search.php。 -
编写
ajax_search.php的内容 这个文件的核心逻辑是获取搜索参数,然后直接输出符合条件的列表HTML。<?php require_once(dirname(__FILE__)."/../include/common.inc.php"); require_once(DEDEINC."/arc.searchview.class.php"); // 获取AJAX传来的参数 $keyword = isset($keyword) ? trim($keyword) : ''; $typeid = isset($typeid) ? intval($typeid) : 0; if (empty($keyword)) { echo '<div class="search-result-empty">请输入搜索关键词</div>'; exit; } // 构建搜索SQL条件 $addsql = ""; if ($typeid > 0) { $typeid = GetSonIds($typeid); $addsql .= " And arc.typeid in({$typeid})"; } // 实例化搜索类 $search = new SearchView(); $search->Init(); $search->keyword = $keyword; $search->AddSql($addsql); // 获取搜索结果 $result = $search->GetResult(); // 解析结果并输出HTML $ctp = new DedeTagParse(); $ctp->SetNameSpace('dd', '', ''); $ctp->LoadSource($result); if (empty($result)) { echo '<div class="search-result-empty">没有找到相关内容</div>'; } else { $items = ''; while ($row = $ctp->GetArcRow()) { $items .= '<li>'; $items .= '<a href="' . $row['arcurl'] . '" title="' . $row['title'] . '">' . $row['title'] . '</a>'; $items .= '<span>' . date('Y-m-d', $row['senddate']) . '</span>'; $items .= '</li>'; } echo $items; } ?> -
修改前端模板,添加AJAX搜索逻辑 在您的列表页或内容页模板中,修改搜索框的HTML,并添加JavaScript代码。
<!-- 搜索框 --> <form name="formsearch" onsubmit="return doSearch(this);" action="javascript:void(0);"> <input type="hidden" name="typeid" value="{dede:field.id/}" /> <div class="form-search"> <input type="text" name="keyword" id="search-keyword" class="search-keyword" placeholder="搜索..." /> <button type="submit" class="search-submit">搜索</button> </div> </form> <!-- 搜索结果容器 --> <div id="search-results-container" style="display:none;"> <ul class="search-results-list"> <!-- 结果将通过JS动态插入这里 --> </ul> </div> <script> function doSearch(form) { var keyword = form.keyword.value; if (keyword == '') { alert('请输入搜索关键词'); return false; } var typeid = form.typeid.value; var resultsContainer = document.getElementById('search-results-container'); var resultsList = resultsContainer.querySelector('.search-results-list'); // 显示加载提示(可选) resultsList.innerHTML = '<li>正在搜索...</li>'; resultsContainer.style.display = 'block'; // 使用AJAX发送请求 $.ajax({ url: '/templets/default/ajax_search.php', type: 'GET', data: { keyword: keyword, typeid: typeid }, dataType: 'html', success: function(response) { resultsList.innerHTML = response; }, error: function() { resultsList.innerHTML = '<li>搜索请求失败,请稍后再试。</li>'; } }); return false; // 阻止表单默认提交行为 } </script>- 注意:请确保您的网站已经引入了jQuery库,如果没有,请在
<head>部分添加:<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>。
- 注意:请确保您的网站已经引入了jQuery库,如果没有,请在
使用自定义SQL查询(最灵活,适合开发者)
如果您对PHP和SQL比较熟悉,可以直接在模板中通过自定义查询来实现。
实现原理:
利用织梦的 {dede:sql} 标签,直接编写SQL语句从数据库中查询当前栏目下的内容,并将结果与搜索关键词进行匹配。
操作步骤:
-
在模板中直接调用 在您需要显示搜索结果的地方(您可以创建一个专门的搜索结果页模板),使用以下代码:
<h2>搜索结果</h2> {dede:sql sql="SELECT id, title, arcurl, description, typeid, pubdate FROM `#@__archives` WHERE (title LIKE '%[field:keyword/]%') OR (description LIKE '%[field:keyword/]%') AND typeid IN ([field:typeid/]) ORDER BY pubdate DESC LIMIT 0, 10" } <li> <a href="[field:arcurl/]" title="[field:title/]">[field:title/]</a> <span>[field:pubdate function="MyDate('Y-m-d',@me)"/]</span> </li> {/dede:sql} {dede:if empty=''} <p>抱歉,没有找到与“<strong>[field:keyword/]</strong>”相关的文章。</p> {/dede:if}- 注意:
[field:keyword/]和[field:typeid/]是占位符,你需要通过PHP在调用前给它们赋值,这个方法通常需要一个独立的PHP文件来处理请求,然后将结果传递给模板。LIKE '%关键词%'是模糊匹配,性能不如全文索引。LIMIT 0, 10用于限制返回结果的数量。
- 注意:
-
创建一个独立的PHP处理文件(更规范的写法) 创建一个文件,
custom_search.php,放在根目录。<?php require_once(dirname(__FILE__)."/include/common.inc.php"); require_once(DEDEINC."/arc.partview.class.php"); // 获取搜索参数 $keyword = isset($keyword) ? trim($keyword) : ''; $typeid = isset($typeid) ? intval($typeid) : 0; if (empty($keyword)) { ShowMsg('请输入搜索关键词', '-1'); exit; } // 获取当前栏目及其子栏目的ID if ($typeid > 0) { $typeid = GetSonIds($typeid); } // 设置模板变量 $tplVars = array( 'keyword' => $keyword, 'typeid' => $typeid, 'fields' => array( 'keyword' => $keyword, 'typeid' => $typeid ) ); // 实例化一个单页文档类来解析模板 $pv = new PartView(); $pv->SetTemplet($cfg_basedir . $cfg_templets_dir . "/default/custom_search_result.htm"); // 指定你的搜索结果模板 $pv->Display($tplVars); ?>然后创建一个模板文件
custom_search_result.htm如方法三中的{dede:sql}调用部分。
总结与建议
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 方法一 | 最简单,利用织梦原生功能,无需额外文件 | 依赖修改核心文件,升级可能被覆盖 | 个人博客、小型网站,追求快速实现 |
| 方法二 | 用户体验好,无刷新,页面流畅 | 需要一定的JS知识,逻辑稍复杂 | 现代化网站,注重用户体验和交互 |
| 方法三 | 最灵活,完全可控SQL和显示样式 | 需要较强的PHP/SQL基础,开发成本高 | 对搜索有特殊需求(如复杂排序、特殊字段筛选)的复杂项目 |
对于大多数用户,方法一已经足够满足需求,且最稳定,如果您希望有更好的用户体验,方法二是最佳选择。
