WP DEVELOP

EP069. “零结果提示 + wp_localize_script() 让请求网址不再写死”

首页 WordPress 开发课程 LIVE SEARCH(续) · EP069
约 13 分钟· #EP069#LIVE SEARCH(续)
🔒 登录后可标记已读

这一讲先解决「搜索没有结果时该显示什么」——用三元运算符(ternary operator)在模板字符串里做条件判断,因为模板字符串里不能直接写 if 语句。顺手修了一个小体验问题:换搜索词时 spinner 图标没有立刻重新出现,补上 isSpinnerVisible = false 的收尾。最后是这一讲的重点:用 PHP 的 wp_localize_script()get_site_url() 的值传进 JS,变成 universityData.root_url这样 REST API 请求的网址就不再写死是本地开发地址,换到正式服务器或分享主题给别人用都不会失效

涉及文件

  • wp-content/themes/fictional-university-theme/functions.php (修改,university_files() 函数末尾新增 wp_localize_script() 调用)
  • wp-content/themes/fictional-university-theme/src/modules/Search.js (修改,getResults() 加零结果判断 + 用 universityData.root_url 拼接网址)

代码实现

functions.php,加在 university_files() 函数最后(在几个 wp_enqueue_script/wp_enqueue_style 调用之后):

// wp-content/themes/fictional-university-theme/functions.php

function university_files() {
  wp_enqueue_script('googleMap', '//maps.googleapis.com/maps/api/js?key=你的APIKey', NULL, '1.0', true);
  wp_enqueue_script('main-university-js', get_theme_file_uri('/build/index.js'), array('jquery'), '1.0', true);
  wp_enqueue_style('custom-google-fonts', '//fonts.googleapis.com/css?family=Roboto+Condensed:300,300i,400,400i,700,700i|Roboto:100,300,400,400i,700,700i');
  wp_enqueue_style('font-awesome', '//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css');
  wp_enqueue_style('university_main_styles', get_theme_file_uri('/build/style-index.css'));
  wp_enqueue_style('university_extra_styles', get_theme_file_uri('/build/index.css'));

  // 新增:把 PHP 的网站根网址传给 JS,变量名叫 universityData
  wp_localize_script('main-university-js', 'universityData', array(
    'root_url' => get_site_url()
  ));
}

add_action('wp_enqueue_scripts', 'university_files');

Search.jsgetResults() 更新:

// wp-content/themes/fictional-university-theme/src/modules/Search.js

// 修改:网址从写死改成用 universityData.root_url 拼接;加上零结果的三元判断;请求完成后收起 spinner
getResults() {
  $.getJSON(universityData.root_url + "/wp-json/wp/v2/posts?search=" + this.searchField.val(), posts => {
    this.resultsDiv.html(`
      <h2 class="search-overlay__section-title">General Information</h2>
      ${posts.length ? '<ul class="link-list min-list">' : "<p>No general information matches that search.</p>"}
        ${posts.map(item => `<li><a href="${item.link}">${item.title.rendered}</a></li>`).join("")}
      ${posts.length ? "</ul>" : ""}
    `)
    this.isSpinnerVisible = false
  })
}

要点:

  • wp_localize_script(句柄, 变量名, 数组) 三个参数:句柄要跟 wp_enqueue_script('main-university-js', ...) 里注册的名字一致(这样 WordPress 才知道把数据挂在哪个脚本前面);第二个参数是自己取的 JS 全局变量名(这里叫 universityData);第三个参数是一个关联数组,数组里随便加多少个属性,最后在浏览器里查看网页源代码都会变成 universityData 这个对象上对应的属性。
  • get_site_url() 是 WordPress 内建函数,返回当前网站安装的根网址,不管部署到哪个域名都会自动跟着变
  • JS 那边直接把 universityData.root_url 当字符串拼在请求网址最前面即可,不需要额外 import 或声明,wp_localize_script() 已经把它变成了页面里的全局变量。
  • 零结果判断用的是三元运算符:${posts.length ? '<ul...>' : "<p>No general information matches that search.</p>"},判断依据是 posts.length(数组长度是 0 就是假值,大于 0 就是真值);<ul> 的开始标签和结束标签分别用两个独立的三元表达式控制,如果没有结果,<ul>/</ul> 都不输出,只输出提示文字;如果有结果,中间那行 .map() 遍历自然也不会有东西可以遍历,不需要额外处理。
  • 请求成功后加一行 this.isSpinnerVisible = false,让下一次输入新关键词时 spinner 能立刻重新出现(原本这个值请求完成后一直是 true,导致 typingLogic() 里判断「spinner 是否已经显示」时误判)。

[截图:前台搜索 overlay 输入一个搜不到任何结果的关键词,显示"No general information matches that search."提示文字的画面]

Hook / Function 速查

名称类型用途
wp_localize_script($handle, $object_name, $data)WP 内建 function把 PHP 数据以全局 JS 变量的形式注入到指定脚本前面的页面源码里
get_site_url()WP 内建 function返回当前 WordPress 安装的根网址
三元运算符 条件 ? 真值 : 假值JS 语法模板字符串内部不能写 if,用三元运算符做条件输出
Array.lengthJS 数组属性判断数组是否有元素,0 为假值,大于 0 为真值

常见坑

  • 模板字符串里不能直接用 if 语句做条件判断,只能用三元运算符
  • 有些文本编辑器在模板字符串里输入 ${ 时会自动帮你在下面插入一个多余的 },如果没注意到,这个多出来的花括号会打乱后面代码的结构,报错也不好定位,写完记得检查一下有没有莫名多出来的花括号
  • REST API 请求网址如果全程写死本地开发地址(比如带 localhost:3000),部署到正式服务器或者把主题分享给别人用时这段搜索功能会直接失效;wp_localize_script() 让网址动态跟着当前网站走才是正确做法

延伸 / 后续讲座会用到

下一讲 EP070 会做几个搜索体验的小优化。再往后 EP071/072 会开始学习如何让搜索同时覆盖 posts 以外的其他文章类型(pages、professors 等)。

Sources

Udemy:

  • Become a WordPress Developer: Unlocking Power With Code — Section 14, EP069