WP DEVELOP

EP085. “无 JS 搜索页面与表单”

首页 WordPress 开发课程 传统搜索(无 JS) · EP085
约 16 分钟· #EP085#传统搜索(无 JS)
🔒 登录后可标记已读

前面几讲做的搜索 Overlay 依赖 JavaScript,这一讲开始给「JavaScript 被禁用/加载失败」的少数访客做一个兜底方案:新建一个 /search 页面放传统的 HTML 搜索表单,表单直接用 GET 方式提交到网站根目录并带上 WordPress 原生识别的 s 参数(WordPress 传统搜索就是靠 ?s=关键词 这个 URL 格式驱动的)。同时把顶部搜索图标从 <span> 改成指向 /search<a> 链接,让没有 JS 的访客点击后能正常跳转,而有 JS 的访客点击时用 return false 拦截默认跳转行为,继续用回原本的 Overlay。


涉及文件

  • Pages 后台新建页面「Search」(slug: search
  • wp-content/themes/fictional-university-theme/page-search.php (新建)
  • wp-content/themes/fictional-university-theme/header.php (修改)
  • wp-content/themes/fictional-university-theme/src/modules/Search.js (修改)

代码实现

page-search.php(新建,复制自 page.php 再把正文替换成搜索表单)

<?php

  get_header();

  while(have_posts()) {
    the_post();
    pageBanner();
     ?>

    <div class="container container--narrow page-section">

    <?php
      $theParent = wp_get_post_parent_id(get_the_ID());
      if ($theParent) { ?>
        <div class="metabox metabox--position-up metabox--with-home-link">
      <p><a class="metabox__blog-home-link" href="<?php echo get_permalink($theParent); ?>"><i class="fa fa-home" aria-hidden="true"></i> Back to <?php echo get_the_title($theParent); ?></a> <span class="metabox__main"><?php the_title(); ?></span></p>
    </div>
      <?php }
    ?>

    <?php
    $testArray = get_pages(array(
      'child_of' => get_the_ID()
    ));

    if ($theParent or $testArray) { ?>
    <div class="page-links">
      <h2 class="page-links__title"><a href="<?php echo get_permalink($theParent); ?>"><?php echo get_the_title($theParent); ?></a></h2>
      <ul class="min-list">
        <?php
          if ($theParent) {
            $findChildrenOf = $theParent;
          } else {
            $findChildrenOf = get_the_ID();
          }

          wp_list_pages(array(
            'title_li' => NULL,
            'child_of' => $findChildrenOf,
            'sort_column' => 'menu_order'
          ));
        ?>
      </ul>
    </div>
    <?php } ?>

    <!-- 新增:用表单代替原本的 the_content() -->
    <div class="generic-content">
      <form class="search-form" method="get" action="<?php echo esc_url(site_url('/')); ?>">
        <label class="headline headline--medium" for="s">Perform a New Search:</label>
        <div class="search-form-row">
          <input placeholder="What are you looking for?" class="s" id="s" type="search" name="s">
          <input class="search-submit" type="submit" value="Search">
        </div>
      </form>
    </div>

  </div>

  <?php }

  get_footer();

?>

header.php:把两处搜索图标从 <span> 换成 <a>(桌面版和移动版各一处):

<!-- 修改前 -->
<span class="js-search-trigger site-header__search-trigger"><i class="fa fa-search" aria-hidden="true"></i></span>
...
<span class="search-trigger js-search-trigger"><i class="fa fa-search" aria-hidden="true"></i></span>

<!-- 修改后 -->
<a href="<?php echo esc_url(site_url('/search')); ?>" class="js-search-trigger site-header__search-trigger"><i class="fa fa-search" aria-hidden="true"></i></a>
...
<a href="<?php echo esc_url(site_url('/search')); ?>" class="search-trigger js-search-trigger"><i class="fa fa-search" aria-hidden="true"></i></a>

src/modules/Search.jsopenOverlay() 末尾加 return false,阻止链接默认跳转行为(有 JS 时点击图标只弹出 Overlay,不会真的跳去 /search):

openOverlay() {
  this.searchOverlay.classList.add("search-overlay--active")
  document.body.classList.add("body-no-scroll")
  this.searchField.value = ""
  setTimeout(() => this.searchField.focus(), 301)
  this.isOverlayOpen = true
  return false // 新增
}

关键改动点:

  • 表单的 actionesc_url(site_url('/')) 而不是让浏览器默认提交到当前页面 URL——这样不管表单放在哪个页面,提交后都会统一带着 ?s=关键词 跳到网站根目录,这正是 WordPress 原生识别搜索请求的 URL 格式
  • 搜索输入框的 name 属性必须是小写 s,这是 WordPress 约定的搜索参数名,改成别的名字 WordPress 不会认
  • 表单 method 显式写 get(虽然大多数浏览器默认就是 get,但明确写出来更保险),这样搜索词会体现在 URL 里,方便直接分享/加书签
  • esc_url() 包住任何从数据库/配置里输出到 HTML 属性的 URL,是 WordPress 的安全惯例,用来防止被篡改的 URL 值注入恶意代码;这次是为了保护访客,不是为了防止网站本身被黑
  • <label for="s"> 配合 <input id="s">:点击文字标签会自动聚焦到输入框,这是无障碍访问的基本做法

[截图:前台 /search 页面实际效果,标题为 "Search Results" 的搜索表单]


Hook / Function 速查

名称类型用途
site_url($path)WP 内建 function生成指向网站根目录(或指定路径)的完整 URL
esc_url()WP 内建 function安全转义 URL,输出到 HTML 属性前的标准做法

常见坑

  • 表单的 action 忘记指向网站根目录,直接用默认提交行为——如果表单放在别的页面下,提交后 URL 会变成 /该页面/?s=xxx 而不是标准的 WordPress 搜索 URL,虽然依然能查出结果,但不是 WordPress 推荐的标准搜索入口格式
  • openOverlay() 忘记加 return false——不加的话,即使 JS 正常工作,点击搜索图标除了弹出 Overlay,浏览器还是会继续执行链接的默认跳转行为,直接把用户带去 /search

延伸 / 后续讲座会用到

下一讲(EP086)会创建 search.php 主题模板,让搜索结果页脱离默认的 index.php(博客列表)样式,按文章类型分别输出不同格式的结果卡片。


Sources

Udemy:

  • Become a WordPress Developer: Unlocking Power With Code — Section 17, EP085