如何织梦搜索当前栏目内容?

99ANYc3cd6
预计阅读时长 29 分钟
位置: 首页 织梦建站 正文

使用织梦自带搜索(最简单,但有限制)

织梦默认的搜索是全站搜索,但我们可以通过一个“小技巧”来限制它只搜索当前栏目。

织梦搜索当前栏目内容
(图片来源网络,侵删)

实现原理: 在搜索页面的URL中,通过一个隐藏的表单字段(如 typeid)来传递当前栏目的ID,然后修改搜索程序,让它只搜索指定栏目ID下的内容。

操作步骤:

  1. 在列表页或内容页添加搜索框 在您需要显示搜索框的模板文件中(list_article.htmarticle_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 的值传递给搜索程序。
  2. 修改搜索程序文件 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查询语句中,从而实现只搜索指定栏目。
  3. 清空缓存并测试 修改完文件后,登录织梦后台,点击“生成” -> “一键更新站点缓存”,然后刷新您的页面,在搜索框中输入关键词进行测试。


使用AJAX无刷新搜索(用户体验好)

如果不想刷新页面就能看到搜索结果,可以使用AJAX技术。

实现原理: 与方法一类似,但搜索请求通过JavaScript发送到后台,后台处理完数据后,再将结果以HTML片段的形式返回,最后由JavaScript动态插入到页面中。

操作步骤:

  1. 创建一个专门处理AJAX搜索的文件 在您的模板目录(/templets/default/)下新建一个文件,命名为 ajax_search.php

  2. 编写 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;
    }
    ?>
  3. 修改前端模板,添加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>

使用自定义SQL查询(最灵活,适合开发者)

如果您对PHP和SQL比较熟悉,可以直接在模板中通过自定义查询来实现。

实现原理: 利用织梦的 {dede:sql} 标签,直接编写SQL语句从数据库中查询当前栏目下的内容,并将结果与搜索关键词进行匹配。

操作步骤:

  1. 在模板中直接调用 在您需要显示搜索结果的地方(您可以创建一个专门的搜索结果页模板),使用以下代码:

    <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 用于限制返回结果的数量。
  2. 创建一个独立的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基础,开发成本高 对搜索有特殊需求(如复杂排序、特殊字段筛选)的复杂项目

对于大多数用户,方法一已经足够满足需求,且最稳定,如果您希望有更好的用户体验,方法二是最佳选择。

-- 展开阅读全文 --
头像
dede无法上传图片怎么办?
« 上一篇 今天
织梦网站栏目无法更新,原因何在?
下一篇 » 今天

相关文章

取消
微信二维码
支付宝二维码

目录[+]