您可能还不知道,有一个很棒的资源叫做 Quotes on Design,它提供由我们自己的 Chris Coyier 策划的关于设计的有趣引言。
到目前为止,Quotes on Design (QoD) 使用了一些自定义代码来查询 WordPress 数据库并提供引言。这用于网站本身,以及用于其 API 以允许在外部网站上使用。随着即将推出的 WordPress JSON REST API 的激动人心,我们认为使用 WP API 而不是我们自己的自定义代码重建网站会很有趣。

以下是我们将要介绍的内容
- 设置 API
- 查询 API 以获取随机引言
- 对该引言做一些有趣的事情
- 自定义 API 以删除未使用的信息
- 使用新的 QoD JSON REST API 为您的网站获取精美的引言
警告! WP JSON REST API 仍在开发中,查询接口可能会在最终版本发布之前发生变化。我们会尽力更新本教程,以防出现任何更改。我们不建议在任何超重要的网站上使用 WP API,除非您是超专业的 WordPress 开发人员,在这种情况下,您可能可以直接跳过这篇文章,对吧?
安装 WP API
WP API 作为插件打包,可在 WordPress.org 插件库中获取。这意味着您可以
- 打开您的 WordPress 仪表板
- 转到插件 → 添加新插件
- 搜索“WP API”
- 安装、激活,您就完成了
让我们开始深入了解!
获取随机文章
对于 QoD,我们想在主页上添加一些简单的功能:单击一个按钮,并从 API 中重新加载一个随机引言。
WP API 包含多个端点,您可以使用它们从数据库中读取信息,包括 元数据、附件、用户 - 实际上,存储在标准 WP 数据库中的任何内容在某种程度上都是可访问的。
对于我们的用例,我们只需要获取一个随机文章。我们从 /wp-json/posts
端点开始,这本质上就像运行 WP_Query
一样,如果您熟悉 WordPress 开发,就会明白。以下是基本端点 URL
http://quotesondesign.com/wp-json/posts
在没有任何查询参数的情况下访问该 URL 会以 JSON 格式返回默认的文章列表 - 本质上,与您在博客页面上看到的一样。
[
{
"ID": 2328,
"content": "<p>Everything we do communicates.</p>\n",
/* ...snip most of the fields... */
"title": "Pete Episcopo",
"type": "post"
},
{
"ID": 2326,
"content": "<p>The only “intuitive” interface is the nipple. After that it’s all learned.</p>\n",
/* ...snip most of the fields... */
"title": "Bruce Ediger",
"type": "post"
},
{
"ID": 2323,
"content": "<p>Only show work you like, or you’ll end up being hired to do things you don’t like.</p>\n",
/* ...snip most of the fields... */
"title": "Victoria Pater",
"type": "post"
}
]
请注意,引言的 ID 是连续的:它们代表网站上最新的三条引言。
对于我们的设计,我们只需要一个文章,并且希望它被随机选择。我们需要对结果进行过滤,并且可以使用与调用 WP_Query
或 get_posts
时相同的参数来实现。
在这种情况下,我们需要两个参数
orderby
参数需要为rand
,以获取随机文章posts_per_page
参数需要为1
,以将结果限制为单个文章
请查看 WP_Query 手册条目 上所有可用参数的列表。
我们使用 filter
查询变量作为数组,通过 URL 传递这些参数,如下所示
http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1
以下是我们使用经过过滤的 URL 从 WP API 获取到的内容
[
{
"ID": 2153,
"author": {
"ID": 2,
"URL": "https://css-tricks.cn",
"avatar": "http://0.gravatar.com/avatar/8081b26e05bb4354f7d65ffc34cbbd67?s=96",
"description": "",
"first_name": "Chris",
"last_name": "Coyier",
/* ...snip some fields... */
},
"comment_status": "closed",
"content": "<p>Wonderfully designed > beautifully designed. Any day.</p>\n",
"date": "2013-06-27T08:34:04",
"date_gmt": "2013-06-27T16:34:04",
"date_tz": "Etc/GMT-8",
"excerpt": "<p>Wonderfully designed > beautifully designed. Any day.</p>\n",
"featured_image": null,
"format": "standard",
"guid": "http://quotesondesign.com/?p=2153",
"link": "http://quotesondesign.com/daniel-burka-2/",
"menu_order": 0,
"meta": {
/* ...snip some fields... */
},
"modified": "2013-06-27T08:34:04",
"modified_gmt": "2013-06-27T16:34:04",
"modified_tz": "Etc/GMT-8",
"parent": null,
"ping_status": "closed",
"slug": "daniel-burka-2",
"status": "publish",
"sticky": false,
"terms": {
/* ...snip some fields... */
},
"title": "Daniel Burka",
"type": "post"
}
]
每次刷新经过过滤的 URL 时,我们都会得到一条不同的引言。太棒了!
您会注意到,我在最后一个片段中包含了更多 WP API JSON 响应。这里有很多信息 - 即使我隐藏了元数据、作者和术语。
出于我们的目的,我们不需要大多数信息。另外,不包含所有信息更有效率 - 所以让我们把它去掉!
从 JSON 响应中删除字段
一位读者写信说,您不再需要执行此操作,因为现在 API 中有 一个 _filter
参数。
我们需要过滤 API 返回的数据,幸运的是 WP API 为我们提供了我们需要的过滤器,叫做 json_prepare_post
。要使用它,我们需要 创建一个新的插件,其中包含以下代码片段
function qod_remove_extra_data( $data, $post, $context ) {
// We only want to modify the 'view' context, for reading posts
if ( $context !== 'view' || is_wp_error( $data ) ) {
return $data;
}
// Here, we unset any data we don't want to see on the front end:
unset( $data['author'] );
unset( $data['status'] );
// continue unsetting whatever other fields you want
return $data;
}
add_filter( 'json_prepare_post', 'qod_remove_extra_data', 12, 3 );
激活我们的插件后,我们会得到一个更小的 JSON 响应,其中只包含我们用例所需的 信息
[
{
"ID": 686,
"content": "<p>My secret is being not terrible at a lot of things. </p>\n",
"link": "http://quotesondesign.com/moby/",
"title": "Moby"
}
]
向 JSON 响应中添加字段
既然我们已经完成了从 JSON 数据中删除不必要的信息,那么为保持平衡,添加一些我们自己的自定义字段也是很合适的。打蜡,打蜡。
一些引言有一个叫做“来源”的自定义元数据字段,Chris 使用它来链接到引言的原始来源(如果它在线上可用)。让我们使用与以前删除数据时相同的 json_prepare_post
过滤器将该元数据添加到 JSON 响应中。在同一个插件中,我们添加以下函数
function qod_add_custom_meta_to_posts( $data, $post, $context ) {
// We only want to modify the 'view' context, for reading posts
if ( $context !== 'view' || is_wp_error( $data ) ) {
return $data;
}
$source = get_post_meta( $post['ID'], 'Source', true );
if ( ! empty( $source ) ) {
$data['custom_meta'] = array( 'Source' => $source );
}
return $data;
}
add_filter( 'json_prepare_post', 'qod_add_custom_meta_to_posts', 10, 3 );
添加了该额外的字段后,以下是 JSON 响应的样子
[
{
"ID": 2039,
"content": "<p>Communication that doesn’t take a chance doesn’t stand a chance.</p>\n",
"custom_meta": {
"Source": "<a href="http://altpick.com/spot/segura/segura.php">article</a>"
},
"link": "http://quotesondesign.com/carlos-segura/",
"title": "Carlos Segura"
}
]
现在我们拥有了准确的所需信息,让我们使用 JSON API 通过 AJAX 在主页上加载随机引言。
从 JSON API 中获取和使用数据
在 QoD 的主页上,我们有一个按钮来获取另一个引言

使用 jQuery 事件处理程序和 jQuery.ajax 函数,我们获取一个引言并使用以下代码片段更新 HTML
jQuery( function( $ ) {
$( '#get-another-quote-button' ).on( 'click', function ( e ) {
e.preventDefault();
$.ajax( {
url: '/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1',
success: function ( data ) {
var post = data.shift(); // The data is an array of posts. Grab the first one.
$( '#quote-title' ).text( post.title );
$( '#quote-content' ).html( post.content );
// If the Source is available, use it. Otherwise hide it.
if ( typeof post.custom_meta !== 'undefined' && typeof post.custom_meta.Source !== 'undefined' ) {
$( '#quote-source' ).html( 'Source:' + post.custom_meta.Source );
} else {
$( '#quote-source' ).text( '' );
}
},
cache: false
} );
} );
} );
现在,当按下按钮时,新的随机引言会自动加载。试试看。
在您的网站上使用 API
您可以使用 API 查询 Quotes on Design,以在您自己的网站上显示精美的引言。我们已经更新了 API 页面 以使用新的 WP JSON API。如前所述,WP API 可能会发生变化,因此不要在超重要的网站上依赖此 API。
更多 API 好处即将到来
WP API 的开发正在进行中,人们对看到人们可以用它构建什么感到非常兴奋。我们的示例非常基础,但 JSON API 的想法已经让我们开始思考各种可能性。
查看 Quotes on Design,并在评论中分享您的想法和问题。如果您有想在网站上看到的精彩引言,请 提交!
嘿,Andy,感谢分享!很高兴看到 API 在实践中的示例。
顺便说一下,从实际的角度来看,API 实际上是 1.2.x 版本的稳定版本,而应该被提议用于核心包含的版本将是 2.x 版本,而 2.0 现在是测试版。这篇文章指出它还没有达到 1.0 版本,这是不准确的。
API 有很多很棒的潜在用例,我很高兴看到人们用它来做更多事情。我实际上正在我的网站上使用它来实现广告投放系统。我认为我们将在未来看到各种令人兴奋的用例。
感谢 Brian,您说得完全正确:1.0 是旧闻。已修复!
这是一个非常基础的 API 示例,我相信我们很快就会被人们用它做的事情所震撼。
不想贬低——而不是最近的WordPress文章——如果这里要使用非CSS相关的代码,我希望它与静态网站生成器有关。我真的很希望更多网站设计师/开发人员熟悉它们,这样我们就可以让更多人离开WordPress及其同类,并关闭因其安全漏洞(以及其编写不良的插件中更频繁的漏洞)而导致的反复出现的僵尸网络。
这是一个有效的观点。这就是为什么我计划只使用WordPress后台并重新创建前端(不受WP插件、主题和漏洞的影响),如CSS tricks上的这篇帖子所示https://css-tricks.cn/thoughts-on-an-api-first-wordpress/
我有一个关于他方法的问题。
每次你点击网站上的按钮,都会向WP API发出一个HTTP请求。我说的对吗?
我计划使用WordPress作为我网站的API,但我无法想象这样做。因为假设Quotes on Design网站变得非常受欢迎。受欢迎到,比如,4000多人同时反复点击按钮。API调用可能会使安装WordPress的服务器崩溃。
有什么好的解决方案来“缓存”这些API调用?我们应该设想创建一个CRON作业,它会自动获取所有(然后只有新的报价)——并将它们放在本地数据库或文件存储中?) 并在QoD的服务器上进行随机报价选择?
是否有现有的系统可以帮助我管理像这样的API调用?
非常感谢!
是的,你可能想缓存每个唯一的URL,并在与该URL相关的帖子更新时使缓存失效。我不知道现有的缓存插件是否开箱即用地处理API URL,但我预计一旦API获得更多关注,它们就会处理API URL。
感谢您的文章!
我只想补充一点,当我写我的关于 API优先WordPress的思考 在CSS-Tricks上,我提到了几个我在WP-API上找不到的功能,这导致我开发了自己的自定义解决方案,其中主要功能是能够用单个请求请求多个内容批次。
对于那些有兴趣在使用WP-API的同时仍然拥有该功能的人,我创建了一个扩展了WP-API并实现了该功能的插件。它可以在GitHub上获得。
您好,
我尝试使用WP-API v 2.0运行您的代码,但它不起作用。我尝试从$data对象中取消设置一些键,但对端点的调用仍然返回它们。
我们正在运行最新稳定版本。2.0仍在开发中——但当2.0发布时,我们会(尝试)更新这篇文章!
很棒的资源。我看到了很多关于REST API的文档,但很高兴找到一些能让像我这样的API新手实际尝试一个工作项目的东西。
看看它能多容易地集成到Angular项目中将很有趣。
您好Andy,
很棒的想法。但我很好奇,我如何在里面使用我的自定义报价?
嗨Daniel,
你可能需要创建自己的“Quotes on Design” WordPress网站——除非我误解了你的目标?
这很有帮助,您能解释一下您是如何在每次点击时实现漂亮的URL的吗?因为我在代码中没有看到这个方法。
有趣的是,我原本以为这种方法对SEO来说不太好,因为页面可能无法被索引,但看来我错了,我在谷歌上快速搜索了“site:http://quotesondesign.com/”,所有报价似乎都被索引了,这真是个好消息。
我想知道Yoast是否负责这部分?
我认为这部分是由Chris处理的——每个报价都在自己的URL上,但他使用了一些JS来替换URL
我想与您分享我们目前正在开发的这个插件。它是用于将WordPress作为Ember的后端。
https://npmjs.net.cn/package/ember-cli-to-wp-theme
只是想提醒一下,如果报价中有未转义的撇号,QoS上的推文链接会断开——例如:http://quotesondesign.com/nate-simpson/
更正一下… 实际上行为有点奇怪。如果我加载一个报价并点击推文链接,它不会显示完整的摘录。但是如果我重新加载页面并再次点击推文链接,它会正确填充推文。如果我在点击之前刷新页面一次,推文也会正常工作。
感谢这篇帖子。非常有用!
我注意到的一件事是,虽然URL会更新(这很酷),但后退按钮不起作用,而这对于能够返回到上一个报价也很有用。
嗨Andy!这篇文章非常有用,我在使用wp api获取数据时遇到了一些错误,但你的帖子解决了我的问题。感谢您与我们分享这篇帖子。
您好Andy,
非常非常有用的帖子,非常感谢
但我对WP API只有一个问题,我必须使用私有查询过滤器来使用偏移参数,但我无法理解身份验证。如果您有任何解决方案,这将非常有帮助
谢谢
除了链接到WP API关于身份验证的文档,我想我帮不了你太多。你也可以尝试在WordPress StackExchange上发布你的问题——确保提供大量细节。
非常感谢你
关于:是的,你可能想缓存每个唯一的URL,
是否可以使用瞬态与API?对于“小”的重复请求,我通常更喜欢将结果瞬态化,这样我就不必一次又一次地访问数据库。
是的,当然可以!您也可以使用缓存插件(这将避免对瞬态的数据库查询),假设您的唯一API URL在每次请求时都发送相同的内容。
您好Andy,
我尝试使用您的代码,但我无法删除作者数据。我可以删除简单的键值数据,但当它像作者一样是数组时——你的方法不起作用。你有什么线索吗?
嗨Lucas!我不知道——我想
unset
应该可以解决问题。你能在这里或在Gist上发布一个代码片段,这样我们就可以深入研究吗?嗨Lucas,我在gist上评论了。对我来说似乎有效,但我们可以深入研究!
嗨——这是我的代码:https://gist.github.com/anonymous/1375b3f28d125354e5ff
嗨Andy,我想知道你是否知道如何为特定帖子类型取消设置$data?上述方法对帖子有效,但如果我添加帖子类型,取消设置将不起作用。例如:/posts/?type=post_type
你确定你的代码正在执行吗?尝试在你要取消设置的位置添加 `var_dump( $data ); exit;` 并访问该页面。代码到达那里了吗?如果没有,它在哪里停止?如果有,`$data` 变量的状态如何?我会从这里开始。
抱歉,我试图取消设置 curl 的特定值。我做了 var dump,所有内容都通过了。我正在使用这行代码:curl -i localhost/wp-json/posts?type=custom_post_type。自定义帖子类型是我创建的自定义帖子类型。如果我只对帖子进行 curl,取消设置的内容会被删除,但如果我使用 ?type=custom_post_type 版本,取消设置的值仍然会出现。
我假设 var dump 在 /posts?type=custom_post_type 上不起作用。我只是不知道为什么,或者是否需要在您上面编写的函数中添加一些特定的内容才能使它与特定帖子类型一起使用。