在我的 日常工作 中,我们拥有大约 1000 个网站,分布在 30 个 WordPress 多站点安装中。这些安装都运行许多相同的插件和设置,尤其是在网络级别。这导致我们的员工浪费了大量时间:他们必须在 30 个安装中手动重复相同的设置。因此,我们正在转向我称之为“远程控制 WordPress” 的方法。
文章系列
第 1 部分:远程控制 WordPress 的 WP REST API(您当前所在位置!)
第 2 部分:OAuth1 的 OAuth 乐趣
第 3 部分:远程控制 WordPress 的扩展
我们将其中一个安装指定为“控制”安装,我们在其中配置网络设置,然后其他 30 个“客户端”安装从控制安装获取其网络设置。
我需要几篇文章才能全面阐述这一点。我希望您能仔细研读每一个细致入微和晦涩难懂的细节。这种方法有可能每年为我们节省数十个工时,并且大大降低了人为错误的几率。点击次数越少,错误就越少!这是一种棘手且新颖的方法,但我对此感到兴奋。
在深入探讨之前,先来个概述
- 控制安装通过 WP REST API V2 插件公开数据。
- 控制安装运行一个自定义插件,用于将网络设置添加到 WP API(默认情况下 WP API 中没有这些设置)。此自定义插件还注册了一个全局变量,该变量为我们提供了一种以编程方式区分控制安装和其他 30 个客户端安装的方法。
- 控制安装运行 OAuth1 插件,以防止设置被公开浏览,但将其暴露给来自客户端安装的脚本请求。
- 控制安装和我们的 30 个客户端安装都运行许多“功能”插件:提供常用 WordPress 技巧的自定义网络插件,例如在 wp-login 屏幕上显示自定义徽标。
- 控制安装和我们的 30 个客户端安装都运行一个自定义插件来管理网络设置。它为我们的功能插件提供了一个抽象层,以便从控制安装获取其设置。
跟随操作所需内容
- 两个 WordPress 多站点安装:一个将作为控制安装,另一个将充当客户端安装。在我的示例中,控制安装将是我的个人网站,客户端安装将是我的本地 MAMP。在撰写本文时,这两个安装都使用 WordPress 4.5.3 版本。在本文中,我们只需要控制安装。后续文章将涉及客户端安装。
- 总共五个插件,正如我上面提到的那样。其中一些在 GitHub 上,一些在 .org 仓库中。一些是我编写的,一些是由比我聪明得多的人编写的。其中一些将来可能会成为核心的一部分,一些只是为了演示。我将在需要时分别介绍它们。本文将需要五个插件中的两个。
- 主题并不重要,但我的示例将使用 twentysixteen 主题。如果您在跟随操作过程中遇到任何问题,模仿此主题将是一个不错的实践。
到目前为止,您都理解了吗?我意识到这是一个快速的概述,但就像中学舞会结束时一样,我们即将放慢速度。本文其余部分的目标是在我们的控制安装上将网络设置公开到 WP API。我们将在后续文章中介绍其余组件。启动您的测试安装并跟随操作!
JSON 返回值
好的,在您的控制安装上,尝试浏览 http://example.com/wp-json/wp/v2/posts
。这应该会返回 404 错误。

现在安装并网络激活 WP REST API V2 插件,然后再次浏览 /wp-json/wp/v2/posts
。您应该会得到类似以下内容的结果

太棒了!您现在有了 JSON 数据。可以四处浏览一下,使用 文档中的端点 作为指南——或者更好的是,使用 JSON 响应本身中的链接 URL。有关更多详细信息,还可以查看 Andy Adams 关于通过 API 获取帖子的 这篇优秀的文章。
您可能会在文档中注意到,网络选项不可用于获取,但我们很快就会解决这个问题。现在,只需在您的控制服务器上加载 /wp-json/css_tricks_wp_api_control/v1/
URL 并注意 404 错误。然后,安装并网络激活我的 CSS Tricks WP API Control 插件。现在,该 /wp-json/css_tricks_wp_api_control/v1/
URL 应该可以为您工作,并返回有关我的插件注册的 network_settings
路由的一些数据。

如果足够仔细地观察,您会注意到响应中最有趣的部分
"args":{"meta_key":{"required":true}}
这表示我的端点接受一个名为 meta_key
的参数,并且该参数是必需的。
那么,/wp-json/css_tricks_wp_api_control/v1/network_settings
— 这个 URL 是什么意思?/wp-json/
部分对于 WP API 来说始终存在。这仅仅意味着您正在获取 JSON 数据。/css_tricks_wp_api_control/
部分是我的插件的命名空间。请注意,核心使用 /wp/
命名空间,例如上面帖子示例中的命名空间。/v1/
表示这是我的插件使用的端点的版本 1。如果我想破坏向后兼容性,可以更新此版本号,但在其他情况下,我不会在每次更新插件本身的版本号时都更新它。最后,我选择注册 /network_settings/
端点来获取网络设置。
深入了解控制插件
控制插件有两个目的。首先,您会看到 它注册了一个全局变量,CSS_TRICKS_WP_API CONTROL
,其他插件可以嗅探该变量以确定它们是在控制安装上运行还是在客户端安装上运行。
其次,您会看到它注册了网络选项以在 WP API 中进行查询。该文件 进行了详细的注释——请快速阅读一下。现在,我将重点介绍两个函数
callback()
用于从数据库返回网络设置。它需要一个 GET
变量 meta_key
,这为我们提供了一种获取特定网络选项的方法。如果您尝试加载 /wp-json/css_tricks_wp_api_control/v1/network_settings
而没有附加 ?meta_key=whatever
,则会看到它被要求提供。您会收到一条 400 错误,警告您未提供元键。

permission_callback()
指定在请求来自我们自定义路由的数据时,必须提供一些身份验证才能在 WP API 中查看网络设置,否则我们可能会遇到安全问题。我们将在下一篇文章中通过 OAuth1 插件实现此功能。现在,您可以看到,如果您尝试加载 /wp-json/css_tricks_wp_api_control/v1/network_settings?meta_key=whatever
,则需要身份验证。在这种情况下,您会收到一条 403 错误,警告您未进行身份验证。

如果您有兴趣在不处理身份验证的情况下浏览 network_settings
端点,您可以 省略对 permissions_callback
的调用,或者使其始终返回 TRUE
,但请注意,这是一个安全漏洞。
此文件本可以以完全不同的方式编写。对于更复杂的端点,最好 扩展 WP Rest Controller。我认为这对于我们的情况来说有点过头了,当然这本身就是一个教程。
后续步骤
在这一点上,您可能会有几个不同的疑问。
其中一个是身份验证。客户端安装如何才能通过 permission_callback()
?我们将在下一篇文章中通过与 OAuth1 插件的漫长而残酷的斗争来实现这一点。
另一个是 DRY/WET。如果我们的 30 个客户端安装运行许多功能插件,如果所有这些功能插件都对控制安装进行硬编码查询,那岂不是很麻烦?因此,我们将编写一个抽象层,所有功能插件都可以使用它来查询控制博客。控制博客甚至会使用它来获取自身设置!令人兴奋的事情;我将在本系列的第三篇也是最后一篇文章中对此进行说明。
然后是性能。每次我们需要一个糟糕的设置时,都要进行一个 HTTP 请求?不。我们将缓存结果,我将在第三篇文章中演示这一点。
更一般地来说,你可能只是觉得这看起来像是很多工作。对此,我想说,相比于什么?我写这个系列是因为我认为它比让员工管理 30 个安装中的相同设置要好。我相信到最后,你可能会同意我的观点!
其他资源
如果你在理解到目前为止的内容时遇到困难,以下是一些最佳的下一步去处。
- 购买WROX 插件开发书籍就像给自己买了一份职业生涯。
- Torque 的 WP API 书籍。这些人运营着 WP Engine——还需要我多说吗?
- WP API 文档,其中关于扩展 API的部分与我们到目前为止所涵盖的内容特别相关。
准备了解更多?
如果你已经理解到目前为止的内容,那么在下一篇文章中,准备好迎接与 OAuth 的激烈较量吧!
文章系列
第 1 部分:远程控制 WordPress 的 WP REST API(您当前所在位置!)
第 2 部分:OAuth1 的 OAuth 乐趣
第 3 部分:远程控制 WordPress 的扩展
从某种程度上说,奇怪的是,WP/WP MS 还没有以某种形式解决这个问题。
如果我理解/浏览正确的话,控制安装或多或少成为了客户端安装的依赖项。缓存放在一边,这是否意味着如果控制安装出现问题,所有 30 个安装都将面临风险?
或者我误解了?(抱歉?)
感谢你的评论!
我想说这取决于你所说的“出现问题”是什么意思。如果你指的是它暂时不可用,比如 DDoS 攻击,那么有几个选项。
1) 也许你隐藏在像 CloudFlare 的“始终在线”功能后面。
2) 你敏锐地提到了缓存。在系列的后面,我将演示如何通过将来自控制端的请求结果存储为客户端安装上的瞬时数据来缓存这些结果。如果你愿意,你可以在那里添加一些逻辑,如果来自控制端的响应为 40x/50x/假值,则不要更新客户端上的瞬时数据。
不错的文章——期待着我真正“需要”它的一天。
仅供参考:“pour” 是让液体溢出容器,我认为你希望我们做的事情——“pore” 是粉刺的组成部分[当然,我并不是在为那些在大洋彼岸的人说话,他们能够用“e”做一些我们这边的人无法做到的事情]
我也对此感到不确定!感谢你的关注。我最终采用了这里的建议
http://grammarist.com/spelling/pore-over-pour-over/
这表明,
完全期待你的下一篇文章……我曾经与 OAuth1 插件进行过几次“漫长而残酷的战斗”,每次都惨败而归……
我不确定是否错过了什么,但是你的使用场景不是使用 WP-CLI 的一个很好的例子吗?
我想这取决于谁在输入命令!我们的设置管理员的技能水平或职业发展路径并不适合让他们拥有对数百个实时域的命令行访问权限。
即使他们具备这样的能力,听起来你所说的也是控制端向客户端推送的场景。我更喜欢客户端从控制端拉取的场景,因为这样可以减少错误破坏客户端数据的可能性。