为会员制 WordPress 网站构建搜索弹窗

大多数 WordPress 搜索教程在教你向页眉添加一个小部件后就结束了。

当你拥有付费课程或私密视频等受限内容时,这种方法就会失效。默认搜索会将你的私密内容的标题泄露给未登录的访客。

我为一个健身会员网站构建了一个实时搜索弹窗。该网站使用了 WordPress、WooCommerce、Divi、LearnDash 和 WishList Member。

以下是如何构建一个尊重付费墙的搜索功能的方案。

架构设计

我使用了一个具有权限感知过滤功能的统一索引。选择这种方式是为了确保未登录用户永远不会看到仅限会员阅读的文章标题或摘要。

UI 使用一个图标来打开全屏覆盖层。这节省了移动端的空间,且比拥挤的输入栏看起来更整洁。

后端实现

所有操作都通过子主题中的单个自定义 REST 路由运行。

关键技术规则:

  • 保护依赖项:针对 Relevanssi 等搜索插件使用函数检查。如果插件缺失,搜索应回退到 WordPress 核心功能,而不是导致网站崩溃。
  • 服务端过滤:切勿使用 JavaScript 过滤结果。如果你在浏览器中隐藏了某个结果,数据其实已经存在于网络响应中了。任何使用 DevTools 的人都能看到它。必须在服务器发送响应之前过滤数据。
  • 排除缓存:你必须将搜索 REST 路由从页面缓存中排除。如果你缓存了结果,一名会员的搜索结果可能会被提供给访客,从而泄露私密内容。

前端实现

客户端使用原生 JavaScript。

三个让用户体验(UX)良好的要素:

  • 防抖 (Debounce):在按键后等待 250ms 再发送请求。这可以减少不必要的服务器负载。
  • AbortController:当用户持续输入时,取消之前的请求。这可以防止旧的结果覆盖新的结果。
  • 错误状态:如果 fetch 失败,显示清晰的消息。一个永不停歇的加载动画是非常糟糕的用户体验。

移动端经验教训

我曾尝试将搜索按钮注入到 Divi 移动菜单中。但主题拦截了点击事件,导致按钮无法点击。

解决方法很简单:不要与主题对抗。

我没有将按钮放在菜单内部,而是将其作为独立元素注入到页眉中。这使其脱离了主题的控制,并且更易于点击。

总结

  • 权限控制必须在服务端完成。
  • 从缓存中排除搜索端点。
  • 使用 debounce 和 AbortController 来处理请求。
  • 在将所有 API 数据注入 DOM 之前进行转义,以防止 XSS。
  • 如果页面构建器(page builder)与你的代码冲突,请将元素放在它旁边,而不是放在它里面。

来源:https://dev.to/highcenburg/building-a-search-modal-for-a-membership-gated-wordpress-site-b92