Version Description
(2010-01-08): =
* Added a post_count
response to tag objects
* Fixed a bug with get_author_index
Download this release
Release Info
Developer | dphiffer |
Plugin | JSON API |
Version | 0.7 |
Comparing to | |
See all releases |
Code changes from version 0.5 to 0.7
- json-api.php +1 -1
- models/tag.php +1 -0
- readme.txt +122 -107
- singletons/introspector.php +50 -40
- singletons/query.php +1 -1
- singletons/response.php +7 -2
json-api.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: JSON API
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/json-api/
|
5 |
Description: A RESTful API for WordPress
|
6 |
-
Version: 0.
|
7 |
Author: Dan Phiffer
|
8 |
Author URI: http://phiffer.org/
|
9 |
*/
|
3 |
Plugin Name: JSON API
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/json-api/
|
5 |
Description: A RESTful API for WordPress
|
6 |
+
Version: 0.7
|
7 |
Author: Dan Phiffer
|
8 |
Author URI: http://phiffer.org/
|
9 |
*/
|
models/tag.php
CHANGED
@@ -18,6 +18,7 @@ class JSON_API_Tag {
|
|
18 |
$this->slug = $wp_tag->slug;
|
19 |
$this->title = $wp_tag->name;
|
20 |
$this->description = $wp_tag->description;
|
|
|
21 |
}
|
22 |
|
23 |
}
|
18 |
$this->slug = $wp_tag->slug;
|
19 |
$this->title = $wp_tag->name;
|
20 |
$this->description = $wp_tag->description;
|
21 |
+
$this->post_count = (int) $wp_tag->count;
|
22 |
}
|
23 |
|
24 |
}
|
readme.txt
CHANGED
@@ -1,17 +1,17 @@
|
|
1 |
=== JSON API ===
|
2 |
Contributors: dphiffer
|
3 |
-
Tags: json, api, ajax, cms, admin, integration
|
4 |
Requires at least: 2.8
|
5 |
Tested up to: 2.8
|
6 |
-
Stable tag: 0.
|
7 |
|
8 |
A RESTful API for WordPress
|
9 |
|
10 |
== Description ==
|
11 |
|
12 |
-
This plugin was created for The Museum of Modern Art, whose weblog [Inside/Out](http://moma.org/explore/inside_out) appears within an existing
|
13 |
|
14 |
-
The current release (0.
|
15 |
|
16 |
See the Other Notes section for complete API documentation.
|
17 |
|
@@ -31,24 +31,21 @@ Requests use a simple REST-style HTTP GET or POST. To invoke the API, include a
|
|
31 |
JSON API operates in two modes:
|
32 |
|
33 |
1. *Implicit mode* is triggered by setting the `json` query var to a non-empty value on any WordPress page. The content that would normally appear on that page is returned in JSON format.
|
|
|
34 |
|
35 |
-
|
36 |
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
* `http://www.example.org/?json=1`
|
42 |
-
* `http://www.example.org/?p=47&json=1`
|
43 |
-
* `http://www.example.org/tag/banana/?json=1`
|
44 |
|
45 |
-
Explicit mode:
|
46 |
|
47 |
* `http://www.example.org/?json=get_recent_posts`
|
48 |
* `http://www.example.org/?json=get_post&post_id=47`
|
49 |
* `http://www.example.org/?json=get_tag_posts&tag_slug=banana`
|
50 |
|
51 |
-
|
52 |
|
53 |
* `http://www.example.org/api/get_recent_posts/`
|
54 |
* `http://www.example.org/api/get_post/?post_id=47`
|
@@ -56,13 +53,14 @@ You can also use a different URL syntax for explicit-mode requests if your weblo
|
|
56 |
|
57 |
== Responses ==
|
58 |
|
59 |
-
The standard response format for JSON API is (as you may have guessed) JSON
|
60 |
|
61 |
Here is an example response from `http://localhost/wordpress/?json=1` called on a default WordPress installation (formatted for readability):
|
62 |
|
63 |
{
|
64 |
"status": "ok",
|
65 |
"count": 1,
|
|
|
66 |
"pages": 1,
|
67 |
"posts": [
|
68 |
{
|
@@ -109,11 +107,11 @@ The JSON API reference is split into four sections:
|
|
109 |
|
110 |
1. Request arguments
|
111 |
1. Response objects
|
|
|
112 |
1. Introspection methods
|
113 |
1. Data manipulation methods
|
114 |
|
115 |
-
__About API changes__
|
116 |
-
|
117 |
All methods are currently subject to change until the plugin reaches maturity. Please read the the changelog carefully before updating to subsequent releases.
|
118 |
|
119 |
== 1. Request arguments ==
|
@@ -135,23 +133,20 @@ These arguments are available to modify all introspection methods:
|
|
135 |
* `custom_fields` - Includes values from posts' Custom Fields. Expects a comma-separated list of custom field keys.
|
136 |
* `author_meta` - Includes additional author metadata. Should be a comma-separated list of metadata fields.
|
137 |
|
138 |
-
__About `include`/`exclude` arguments__
|
139 |
-
|
140 |
-
The default behavior includes all post values. You only need to specify one of `include` or `exclude` — the former will implicitly leave out those fields you haven't specified and the latter will implicitly include them. For example, a query of `exclude=comments` will include everything *except* the comments, so there's no need to also specify anything with the `include` argument.
|
141 |
-
|
142 |
-
== 2. Response types ==
|
143 |
|
144 |
-
|
145 |
|
146 |
-
|
147 |
|
148 |
-
|
149 |
-
|
150 |
-
__Naming compatibility__
|
151 |
|
|
|
152 |
Developers familiar with WordPress may notice that many names for properties and arguments have been changed. This was a stylistic choice that intends to provide more clarity and consistency in the interface.
|
153 |
|
154 |
-
|
155 |
|
156 |
* `id` - Integer
|
157 |
* `slug` - String
|
@@ -170,7 +165,7 @@ __Post response object__
|
|
170 |
* `comment_status` - String (`"open"` or `"closed"`)
|
171 |
* `custom_fields` - Object (included by setting the `custom_fields` argument to a comma-separated list of custom field names)
|
172 |
|
173 |
-
|
174 |
|
175 |
* `id` - Integer
|
176 |
* `slug` - String
|
@@ -179,14 +174,15 @@ __Category response object__
|
|
179 |
* `parent` - Integer
|
180 |
* `post_count` - Integer
|
181 |
|
182 |
-
|
183 |
|
184 |
* `id` - Integer
|
185 |
* `slug` - String
|
186 |
* `title` - String
|
187 |
* `description` - String
|
|
|
188 |
|
189 |
-
|
190 |
|
191 |
* `id` - Integer
|
192 |
* `slug` - String
|
@@ -199,7 +195,7 @@ __Author response object__
|
|
199 |
|
200 |
Note: You can include additional values by setting the `author_meta` argument to a comma-separated list of metadata fields.
|
201 |
|
202 |
-
|
203 |
|
204 |
* `id` - Integer
|
205 |
* `name` - String
|
@@ -209,33 +205,62 @@ __Comment response object__
|
|
209 |
* `parent` - Integer
|
210 |
* `author` - Object (only set if the comment author was registered & logged in)
|
211 |
|
212 |
-
|
|
|
|
|
213 |
|
214 |
-
|
215 |
|
216 |
* `http://www.example.com/foo?status=ok`
|
217 |
* `http://www.example.com/foo?status=error`
|
218 |
|
219 |
-
You can
|
|
|
|
|
|
|
|
|
220 |
|
221 |
-
==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
|
223 |
Introspection methods are used to retrieve data from WordPress.
|
224 |
|
225 |
|
226 |
-
|
227 |
|
228 |
Returns an array of recent posts. You can invoke this from the WordPress home page either by setting `json` to a non-empty value (i.e., `json=1`) or from any page by setting `json=get_recent_posts`.
|
229 |
|
230 |
-
Optional arguments
|
231 |
|
232 |
* `page` - return a specific page number from the results
|
233 |
|
234 |
-
Response
|
235 |
|
236 |
{
|
237 |
"status": "ok",
|
238 |
"count": 10,
|
|
|
239 |
"pages": 7,
|
240 |
"posts": [
|
241 |
{ ... },
|
@@ -244,66 +269,61 @@ Response format:
|
|
244 |
]
|
245 |
}
|
246 |
|
247 |
-
Status values: `ok`, `error`
|
248 |
|
249 |
-
|
250 |
-
__Method: `get_post`__
|
251 |
|
252 |
Returns a single post object.
|
253 |
|
254 |
-
One of the following is required
|
|
|
255 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a post URL
|
256 |
* `post_id` - set to the post's ID
|
257 |
* `post_slug` - set to the post's URL slug
|
258 |
|
259 |
-
Response
|
260 |
|
261 |
{
|
262 |
"status": "ok",
|
263 |
"post": { ... }
|
264 |
}
|
265 |
|
266 |
-
Status values: `ok`, `error`
|
267 |
|
268 |
-
|
269 |
-
__Method: `get_page`__
|
270 |
|
271 |
Returns a single page object.
|
272 |
|
273 |
-
One of the following is required
|
274 |
|
275 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a page URL
|
276 |
* `page_id` - set to the page's ID
|
277 |
* `page_slug` - set to the page's URL slug
|
278 |
|
279 |
-
Response
|
280 |
|
281 |
{
|
282 |
"status": "ok",
|
283 |
"page": { ... }
|
284 |
}
|
285 |
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
__Method: `get_date_posts`__
|
290 |
|
291 |
Returns an array of posts/pages in a specific category.
|
292 |
|
293 |
-
One of the following is required
|
294 |
|
295 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a date archive page
|
296 |
* `date` - set to a date in the format `YYYY` or `YYYYMM` or `YYYYMMDD`
|
297 |
|
298 |
-
Optional arguments
|
299 |
|
300 |
* `page` - return a specific page number from the results
|
301 |
|
302 |
-
Response
|
303 |
|
304 |
{
|
305 |
"status": "ok",
|
306 |
"count": 10,
|
|
|
307 |
"pages": 7,
|
308 |
"posts": [
|
309 |
{ ... },
|
@@ -312,28 +332,26 @@ Response format:
|
|
312 |
]
|
313 |
}
|
314 |
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
__Method: `get_category_posts`__
|
319 |
|
320 |
Returns an array of posts/pages in a specific category.
|
321 |
|
322 |
-
One of the following is required
|
323 |
|
324 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a category archive page
|
325 |
* `category_id` - set to the category's ID
|
326 |
* `category_slug` - set to the category's URL slug
|
327 |
|
328 |
-
Optional arguments
|
329 |
|
330 |
* `page` - return a specific page number from the results
|
331 |
|
332 |
-
Response
|
333 |
|
334 |
{
|
335 |
"status": "ok",
|
336 |
"count": 10,
|
|
|
337 |
"pages": 7,
|
338 |
"category": { ... }
|
339 |
"posts": [
|
@@ -343,28 +361,27 @@ Response format:
|
|
343 |
]
|
344 |
}
|
345 |
|
346 |
-
Status values: `ok`, `error`
|
347 |
|
348 |
-
|
349 |
-
__Method: `get_tag_posts`__
|
350 |
|
351 |
Returns an array of posts/pages with a specific tag.
|
352 |
|
353 |
-
One of the following is required
|
354 |
|
355 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a tag archive page
|
356 |
* `tag_id` - set to the tag's ID
|
357 |
* `tag_slug` - set to the tag's URL slug
|
358 |
|
359 |
-
Optional arguments
|
360 |
|
361 |
* `page` - return a specific page number from the results
|
362 |
|
363 |
-
Response
|
364 |
|
365 |
{
|
366 |
"status": "ok",
|
367 |
"count": 10,
|
|
|
368 |
"pages": 7,
|
369 |
"tag": { ... }
|
370 |
"posts": [
|
@@ -374,58 +391,56 @@ Response format:
|
|
374 |
]
|
375 |
}
|
376 |
|
377 |
-
Status values: `ok`, `error`
|
378 |
-
|
379 |
|
380 |
-
|
381 |
|
382 |
Returns an array of posts/pages written by a specific author.
|
383 |
|
384 |
-
One of the following is required
|
385 |
|
386 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on an author archive page
|
387 |
* `author_id` - set to the author's ID
|
388 |
* `author_slug` - set to the author's URL slug
|
389 |
|
390 |
-
Optional arguments
|
391 |
|
392 |
* `page` - return a specific page number from the results
|
393 |
|
394 |
-
Response
|
395 |
|
396 |
{
|
397 |
"status": "ok",
|
398 |
"count": 10,
|
|
|
399 |
"pages": 7,
|
400 |
"author": { ... }
|
401 |
"posts": [
|
402 |
{ ... },
|
403 |
{ ... },
|
404 |
-
|
405 |
]
|
406 |
}
|
407 |
|
408 |
-
Status values: `ok`, `error`
|
409 |
-
|
410 |
|
411 |
-
|
412 |
|
413 |
Returns an array of posts/pages in response to a search query.
|
414 |
|
415 |
-
One of the following is required
|
416 |
|
417 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a search results page
|
418 |
* `search` - set to the desired search query
|
419 |
|
420 |
-
Optional arguments
|
421 |
|
422 |
* `page` - return a specific page number from the results
|
423 |
|
424 |
-
Response
|
425 |
|
426 |
{
|
427 |
"status": "ok",
|
428 |
"count": 10,
|
|
|
429 |
"pages": 7,
|
430 |
"posts": [
|
431 |
{ ... },
|
@@ -434,14 +449,12 @@ Response format:
|
|
434 |
]
|
435 |
}
|
436 |
|
437 |
-
Status values: `ok`, `error`
|
438 |
|
439 |
-
|
440 |
-
__Method: `get_date_index`__
|
441 |
|
442 |
Returns both an array of date page permalinks and a tree structure representation of the archive.
|
443 |
|
444 |
-
Response
|
445 |
|
446 |
{
|
447 |
"status": "ok",
|
@@ -458,16 +471,14 @@ Response format:
|
|
458 |
}
|
459 |
}
|
460 |
|
461 |
-
Note: the tree is arranged by [year]
|
462 |
-
|
463 |
-
Status values: `ok`, `error`
|
464 |
|
465 |
|
466 |
-
|
467 |
|
468 |
Returns an array of active categories.
|
469 |
|
470 |
-
Response
|
471 |
|
472 |
{
|
473 |
"status": "ok",
|
@@ -479,14 +490,12 @@ Response format:
|
|
479 |
]
|
480 |
}
|
481 |
|
482 |
-
Status values: `ok`, `error`
|
483 |
-
|
484 |
|
485 |
== Method: get_tag_index ==
|
486 |
|
487 |
Returns an array of active tags.
|
488 |
|
489 |
-
Response
|
490 |
|
491 |
{
|
492 |
"status": "ok",
|
@@ -498,14 +507,12 @@ Response format:
|
|
498 |
]
|
499 |
}
|
500 |
|
501 |
-
Status values: `ok`, `error`
|
502 |
-
|
503 |
|
504 |
== Method: get_author_index ==
|
505 |
|
506 |
Returns an array of active blog authors.
|
507 |
|
508 |
-
Response
|
509 |
|
510 |
{
|
511 |
"status": "ok",
|
@@ -517,40 +524,48 @@ Response format:
|
|
517 |
]
|
518 |
}
|
519 |
|
520 |
-
Status values: `ok`, `error`
|
521 |
-
|
522 |
|
523 |
-
==
|
524 |
|
525 |
Data manipulation methods are used for saving content back to WordPress.
|
526 |
|
527 |
-
|
528 |
-
|
529 |
The data manipulation methods are still very incomplete.
|
530 |
|
531 |
|
532 |
-
|
533 |
|
534 |
Submits a comment to a WordPress post.
|
535 |
|
536 |
-
Required arguments
|
537 |
|
538 |
* `post_id` - which post to comment on
|
539 |
* `name` - the commenter's name
|
540 |
* `email` - the commenter's email address
|
541 |
* `content` - the comment content
|
542 |
|
543 |
-
Optional arguments
|
544 |
|
545 |
* `redirect` - redirect instead of returning a JSON object
|
546 |
* `redirect_ok` - redirect to a specific URL when the status value is `ok`
|
547 |
* `redirect_error` - redirect to a specific URL when the status value is `error`
|
548 |
-
* `redirect_pending` - redirect to a specific URL when the status value is `pending`
|
|
|
|
|
549 |
|
550 |
-
|
551 |
|
552 |
|
553 |
== Changelog ==
|
554 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
555 |
= 0.5 (2009-11-17): =
|
556 |
* Initial Public Release
|
1 |
=== JSON API ===
|
2 |
Contributors: dphiffer
|
3 |
+
Tags: json, api, ajax, cms, admin, integration, moma
|
4 |
Requires at least: 2.8
|
5 |
Tested up to: 2.8
|
6 |
+
Stable tag: 0.7
|
7 |
|
8 |
A RESTful API for WordPress
|
9 |
|
10 |
== Description ==
|
11 |
|
12 |
+
This plugin was created for The Museum of Modern Art, whose weblog [Inside/Out](http://moma.org/explore/inside_out) appears within an existing structure built with Ruby on Rails. Instead of reimplementing the site templates as a WordPress theme, we opted for a Rails front-end that displays content served from a WordPress back-end. JSON API provides the necessary interface for retrieving content and accepting comment submissions.
|
13 |
|
14 |
+
The current release (0.6) implements a mostly-complete set of introspection methods and a method for submitting comments. I plan on offering a complete set of authentication & data manipulation methods, but my current focus is on features we're actually using at MoMA.org.
|
15 |
|
16 |
See the Other Notes section for complete API documentation.
|
17 |
|
31 |
JSON API operates in two modes:
|
32 |
|
33 |
1. *Implicit mode* is triggered by setting the `json` query var to a non-empty value on any WordPress page. The content that would normally appear on that page is returned in JSON format.
|
34 |
+
1. *Explicit mode* is triggered by setting `json` to a known method string. See the *API Reference* section below for a complete method listing.
|
35 |
|
36 |
+
= Implicit mode examples: =
|
37 |
|
38 |
+
* `http://www.example.org/?json=1`
|
39 |
+
* `http://www.example.org/?p=47&json=1`
|
40 |
+
* `http://www.example.org/tag/banana/?json=1`
|
|
|
|
|
|
|
|
|
41 |
|
42 |
+
= Explicit mode examples: =
|
43 |
|
44 |
* `http://www.example.org/?json=get_recent_posts`
|
45 |
* `http://www.example.org/?json=get_post&post_id=47`
|
46 |
* `http://www.example.org/?json=get_tag_posts&tag_slug=banana`
|
47 |
|
48 |
+
= With user-friendly permalinks configured: =
|
49 |
|
50 |
* `http://www.example.org/api/get_recent_posts/`
|
51 |
* `http://www.example.org/api/get_post/?post_id=47`
|
53 |
|
54 |
== Responses ==
|
55 |
|
56 |
+
The standard response format for JSON API is (as you may have guessed) [JSON](http://json.org/).
|
57 |
|
58 |
Here is an example response from `http://localhost/wordpress/?json=1` called on a default WordPress installation (formatted for readability):
|
59 |
|
60 |
{
|
61 |
"status": "ok",
|
62 |
"count": 1,
|
63 |
+
"count_total": 1,
|
64 |
"pages": 1,
|
65 |
"posts": [
|
66 |
{
|
107 |
|
108 |
1. Request arguments
|
109 |
1. Response objects
|
110 |
+
1. Plugin hooks
|
111 |
1. Introspection methods
|
112 |
1. Data manipulation methods
|
113 |
|
114 |
+
__About API changes__
|
|
|
115 |
All methods are currently subject to change until the plugin reaches maturity. Please read the the changelog carefully before updating to subsequent releases.
|
116 |
|
117 |
== 1. Request arguments ==
|
133 |
* `custom_fields` - Includes values from posts' Custom Fields. Expects a comma-separated list of custom field keys.
|
134 |
* `author_meta` - Includes additional author metadata. Should be a comma-separated list of metadata fields.
|
135 |
|
136 |
+
__About `include`/`exclude` arguments__
|
137 |
+
By default you get all values included with each post object. Specify a list of `include` values will cause the post object to filter out the values absent from the list. Specifying `exclude` causes post objects to include all values except the fields you list. For example, the query `exclude=comments` includes everything *except* the comments.
|
|
|
|
|
|
|
138 |
|
139 |
+
== 2. Response objects ==
|
140 |
|
141 |
+
This section describes data objects you can retrieve from WordPress and the optional URL redirects.
|
142 |
|
143 |
+
__Status values__
|
144 |
+
All JSON API requests result in a status value. The two basic status values are `ok` and `error`. Additional status values are available for certain methods (such as `pending` in the case of the `submit_comment` method). API methods that result in custom status values include a *custom status values* section in their documentation.
|
|
|
145 |
|
146 |
+
__Naming compatibility__
|
147 |
Developers familiar with WordPress may notice that many names for properties and arguments have been changed. This was a stylistic choice that intends to provide more clarity and consistency in the interface.
|
148 |
|
149 |
+
= Post response object =
|
150 |
|
151 |
* `id` - Integer
|
152 |
* `slug` - String
|
165 |
* `comment_status` - String (`"open"` or `"closed"`)
|
166 |
* `custom_fields` - Object (included by setting the `custom_fields` argument to a comma-separated list of custom field names)
|
167 |
|
168 |
+
= Category response object =
|
169 |
|
170 |
* `id` - Integer
|
171 |
* `slug` - String
|
174 |
* `parent` - Integer
|
175 |
* `post_count` - Integer
|
176 |
|
177 |
+
= Tag response object =
|
178 |
|
179 |
* `id` - Integer
|
180 |
* `slug` - String
|
181 |
* `title` - String
|
182 |
* `description` - String
|
183 |
+
* `post_count` - Integer
|
184 |
|
185 |
+
= Author response object =
|
186 |
|
187 |
* `id` - Integer
|
188 |
* `slug` - String
|
195 |
|
196 |
Note: You can include additional values by setting the `author_meta` argument to a comma-separated list of metadata fields.
|
197 |
|
198 |
+
== Comment response object ==
|
199 |
|
200 |
* `id` - Integer
|
201 |
* `name` - String
|
205 |
* `parent` - Integer
|
206 |
* `author` - Object (only set if the comment author was registered & logged in)
|
207 |
|
208 |
+
== Redirects ==
|
209 |
+
|
210 |
+
The `redirect` response style is useful for when you need the user's browser to make a request directly rather than making proxy requests using a tool like cURL. Setting a `redirect` argument causes the user's browser to redirect back to the specified URL instead of returning a JSON object. The resulting `status` value is included as an extra query variable.
|
211 |
|
212 |
+
For example calling an API method with `redirect` set to `http://www.example.com/foo` will result in a redirection to one of the following:
|
213 |
|
214 |
* `http://www.example.com/foo?status=ok`
|
215 |
* `http://www.example.com/foo?status=error`
|
216 |
|
217 |
+
You can also set separate URLs to handle status values differently. You could set `redirect_ok` to `http://www.example.com/handle_ok` and `redirect_error` to `http://www.example.com/handle_error` in order to have more fine-tuned control over the method result.
|
218 |
+
|
219 |
+
== 3. Plugin hooks ==
|
220 |
+
|
221 |
+
JSON API currently exposes a single [filter hook](http://codex.wordpress.org/Plugin_API#Hooks.2C_Actions_and_Filters) for you to modify the output.
|
222 |
|
223 |
+
== Filter: json_api_encode ==
|
224 |
+
|
225 |
+
This is called just before the output is encoded into JSON format. The value passed will always be an associative array, according to the format described in each method's documentation. Those items described in the *Response objects* section are passed as PHP objects, not associative arrays.
|
226 |
+
|
227 |
+
= Example =
|
228 |
+
|
229 |
+
add_filter('json_api_encode', 'encode_kittens_field');
|
230 |
+
|
231 |
+
encode_kittens_field($response) {
|
232 |
+
if (isset($response['posts'])) {
|
233 |
+
array_walk($response['posts'], 'add_kittens_field');
|
234 |
+
} else if (isset($response['post'])) {
|
235 |
+
add_kittens_field($response['post']);
|
236 |
+
}
|
237 |
+
return $response;
|
238 |
+
}
|
239 |
+
|
240 |
+
add_kittens_field(&$post) {
|
241 |
+
$post->kittens = 'Kittens!';
|
242 |
+
}
|
243 |
+
|
244 |
+
|
245 |
+
== 4. Introspection methods ==
|
246 |
|
247 |
Introspection methods are used to retrieve data from WordPress.
|
248 |
|
249 |
|
250 |
+
== Method: get_recent_posts ==
|
251 |
|
252 |
Returns an array of recent posts. You can invoke this from the WordPress home page either by setting `json` to a non-empty value (i.e., `json=1`) or from any page by setting `json=get_recent_posts`.
|
253 |
|
254 |
+
= Optional arguments =
|
255 |
|
256 |
* `page` - return a specific page number from the results
|
257 |
|
258 |
+
= Response =
|
259 |
|
260 |
{
|
261 |
"status": "ok",
|
262 |
"count": 10,
|
263 |
+
"count_total": 79,
|
264 |
"pages": 7,
|
265 |
"posts": [
|
266 |
{ ... },
|
269 |
]
|
270 |
}
|
271 |
|
|
|
272 |
|
273 |
+
== Method: get_post ==
|
|
|
274 |
|
275 |
Returns a single post object.
|
276 |
|
277 |
+
= One of the following is required =
|
278 |
+
|
279 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a post URL
|
280 |
* `post_id` - set to the post's ID
|
281 |
* `post_slug` - set to the post's URL slug
|
282 |
|
283 |
+
= Response =
|
284 |
|
285 |
{
|
286 |
"status": "ok",
|
287 |
"post": { ... }
|
288 |
}
|
289 |
|
|
|
290 |
|
291 |
+
== Method: get_page ==
|
|
|
292 |
|
293 |
Returns a single page object.
|
294 |
|
295 |
+
= One of the following is required =
|
296 |
|
297 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a page URL
|
298 |
* `page_id` - set to the page's ID
|
299 |
* `page_slug` - set to the page's URL slug
|
300 |
|
301 |
+
= Response =
|
302 |
|
303 |
{
|
304 |
"status": "ok",
|
305 |
"page": { ... }
|
306 |
}
|
307 |
|
308 |
+
== Method: get_date_posts ==
|
|
|
|
|
|
|
309 |
|
310 |
Returns an array of posts/pages in a specific category.
|
311 |
|
312 |
+
= One of the following is required =
|
313 |
|
314 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a date archive page
|
315 |
* `date` - set to a date in the format `YYYY` or `YYYYMM` or `YYYYMMDD`
|
316 |
|
317 |
+
= Optional arguments =
|
318 |
|
319 |
* `page` - return a specific page number from the results
|
320 |
|
321 |
+
= Response =
|
322 |
|
323 |
{
|
324 |
"status": "ok",
|
325 |
"count": 10,
|
326 |
+
"count_total": 79,
|
327 |
"pages": 7,
|
328 |
"posts": [
|
329 |
{ ... },
|
332 |
]
|
333 |
}
|
334 |
|
335 |
+
== Method: get_category_posts ==
|
|
|
|
|
|
|
336 |
|
337 |
Returns an array of posts/pages in a specific category.
|
338 |
|
339 |
+
= One of the following is required =
|
340 |
|
341 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a category archive page
|
342 |
* `category_id` - set to the category's ID
|
343 |
* `category_slug` - set to the category's URL slug
|
344 |
|
345 |
+
= Optional arguments =
|
346 |
|
347 |
* `page` - return a specific page number from the results
|
348 |
|
349 |
+
= Response =
|
350 |
|
351 |
{
|
352 |
"status": "ok",
|
353 |
"count": 10,
|
354 |
+
"count_total": 79,
|
355 |
"pages": 7,
|
356 |
"category": { ... }
|
357 |
"posts": [
|
361 |
]
|
362 |
}
|
363 |
|
|
|
364 |
|
365 |
+
== Method: get_tag_posts ==
|
|
|
366 |
|
367 |
Returns an array of posts/pages with a specific tag.
|
368 |
|
369 |
+
= One of the following is required =
|
370 |
|
371 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a tag archive page
|
372 |
* `tag_id` - set to the tag's ID
|
373 |
* `tag_slug` - set to the tag's URL slug
|
374 |
|
375 |
+
= Optional arguments =
|
376 |
|
377 |
* `page` - return a specific page number from the results
|
378 |
|
379 |
+
= Response =
|
380 |
|
381 |
{
|
382 |
"status": "ok",
|
383 |
"count": 10,
|
384 |
+
"count_total": 79,
|
385 |
"pages": 7,
|
386 |
"tag": { ... }
|
387 |
"posts": [
|
391 |
]
|
392 |
}
|
393 |
|
|
|
|
|
394 |
|
395 |
+
== Method: get_author_posts ==
|
396 |
|
397 |
Returns an array of posts/pages written by a specific author.
|
398 |
|
399 |
+
= One of the following is required =
|
400 |
|
401 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on an author archive page
|
402 |
* `author_id` - set to the author's ID
|
403 |
* `author_slug` - set to the author's URL slug
|
404 |
|
405 |
+
= Optional arguments =
|
406 |
|
407 |
* `page` - return a specific page number from the results
|
408 |
|
409 |
+
= Response =
|
410 |
|
411 |
{
|
412 |
"status": "ok",
|
413 |
"count": 10,
|
414 |
+
"count_total": 79,
|
415 |
"pages": 7,
|
416 |
"author": { ... }
|
417 |
"posts": [
|
418 |
{ ... },
|
419 |
{ ... },
|
420 |
+
...
|
421 |
]
|
422 |
}
|
423 |
|
|
|
|
|
424 |
|
425 |
+
== Method: get_search_results ==
|
426 |
|
427 |
Returns an array of posts/pages in response to a search query.
|
428 |
|
429 |
+
= One of the following is required =
|
430 |
|
431 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a search results page
|
432 |
* `search` - set to the desired search query
|
433 |
|
434 |
+
= Optional arguments =
|
435 |
|
436 |
* `page` - return a specific page number from the results
|
437 |
|
438 |
+
= Response =
|
439 |
|
440 |
{
|
441 |
"status": "ok",
|
442 |
"count": 10,
|
443 |
+
"count_total": 79,
|
444 |
"pages": 7,
|
445 |
"posts": [
|
446 |
{ ... },
|
449 |
]
|
450 |
}
|
451 |
|
|
|
452 |
|
453 |
+
== Method: get_date_index ==
|
|
|
454 |
|
455 |
Returns both an array of date page permalinks and a tree structure representation of the archive.
|
456 |
|
457 |
+
= Response =
|
458 |
|
459 |
{
|
460 |
"status": "ok",
|
471 |
}
|
472 |
}
|
473 |
|
474 |
+
Note: the tree is arranged by `response.tree.[year].[month].[number of posts]`.
|
|
|
|
|
475 |
|
476 |
|
477 |
+
== Method: get_category_index ==
|
478 |
|
479 |
Returns an array of active categories.
|
480 |
|
481 |
+
= Response =
|
482 |
|
483 |
{
|
484 |
"status": "ok",
|
490 |
]
|
491 |
}
|
492 |
|
|
|
|
|
493 |
|
494 |
== Method: get_tag_index ==
|
495 |
|
496 |
Returns an array of active tags.
|
497 |
|
498 |
+
= Response =
|
499 |
|
500 |
{
|
501 |
"status": "ok",
|
507 |
]
|
508 |
}
|
509 |
|
|
|
|
|
510 |
|
511 |
== Method: get_author_index ==
|
512 |
|
513 |
Returns an array of active blog authors.
|
514 |
|
515 |
+
= Response =
|
516 |
|
517 |
{
|
518 |
"status": "ok",
|
524 |
]
|
525 |
}
|
526 |
|
|
|
|
|
527 |
|
528 |
+
== 5. Data manipulation methods ==
|
529 |
|
530 |
Data manipulation methods are used for saving content back to WordPress.
|
531 |
|
532 |
+
__Incomplete__
|
|
|
533 |
The data manipulation methods are still very incomplete.
|
534 |
|
535 |
|
536 |
+
== Method: submit_comment ==
|
537 |
|
538 |
Submits a comment to a WordPress post.
|
539 |
|
540 |
+
= Required arguments =
|
541 |
|
542 |
* `post_id` - which post to comment on
|
543 |
* `name` - the commenter's name
|
544 |
* `email` - the commenter's email address
|
545 |
* `content` - the comment content
|
546 |
|
547 |
+
= Optional arguments =
|
548 |
|
549 |
* `redirect` - redirect instead of returning a JSON object
|
550 |
* `redirect_ok` - redirect to a specific URL when the status value is `ok`
|
551 |
* `redirect_error` - redirect to a specific URL when the status value is `error`
|
552 |
+
* `redirect_pending` - redirect to a specific URL when the status value is `pending`
|
553 |
+
|
554 |
+
= Custom status values =
|
555 |
|
556 |
+
* `pending` - assigned if the comment submission is pending moderation
|
557 |
|
558 |
|
559 |
== Changelog ==
|
560 |
|
561 |
+
= 0.7 (2010-01-08): =
|
562 |
+
* Added a `post_count` response to tag objects
|
563 |
+
* Fixed a bug with `get_author_index`
|
564 |
+
|
565 |
+
= 0.6 (2009-11-30): =
|
566 |
+
* Added `count_total` response
|
567 |
+
* Added `json_api_encode` filter
|
568 |
+
* Fixed bugs in the introspector's `get_current_category` and `get_current_tag`
|
569 |
+
|
570 |
= 0.5 (2009-11-17): =
|
571 |
* Initial Public Release
|
singletons/introspector.php
CHANGED
@@ -69,65 +69,74 @@ class JSON_API_Introspector {
|
|
69 |
if ($wp_category->term_id == 1 && $wp_category->slug == 'uncategorized') {
|
70 |
continue;
|
71 |
}
|
72 |
-
$categories[] = $this->
|
73 |
}
|
74 |
return $categories;
|
75 |
}
|
76 |
|
77 |
-
function get_category($arg) {
|
78 |
-
if (is_object($arg)) {
|
79 |
-
return new JSON_API_Category($arg);
|
80 |
-
} else if (is_numeric($arg)) {
|
81 |
-
$wp_category = get_term_by('id', $arg, 'category');
|
82 |
-
return $this->get_category($wp_category);
|
83 |
-
} else if (is_string($arg)) {
|
84 |
-
$wp_category = get_term_by('slug', $arg, 'category');
|
85 |
-
return $this->get_category($wp_category);
|
86 |
-
} else {
|
87 |
-
return null;
|
88 |
-
}
|
89 |
-
}
|
90 |
-
|
91 |
function get_current_category() {
|
92 |
global $json_api;
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
96 |
}
|
97 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
}
|
99 |
|
100 |
function get_tags() {
|
101 |
$wp_tags = get_tags();
|
102 |
-
return array_map(array(&$this, '
|
103 |
-
}
|
104 |
-
|
105 |
-
function get_tag($arg) {
|
106 |
-
if (is_object($arg)) {
|
107 |
-
return new JSON_API_Tag($arg);
|
108 |
-
} else if (is_numeric($arg)) {
|
109 |
-
$wp_tag = get_term_by('id', $arg, 'post_tag');
|
110 |
-
return $this->get_tag($wp_tag);
|
111 |
-
} else if (is_string($arg)) {
|
112 |
-
$wp_tag = get_term_by('slug', $arg, 'post_tag');
|
113 |
-
return $this->get_tag($wp_tag);
|
114 |
-
} else {
|
115 |
-
return null;
|
116 |
-
}
|
117 |
}
|
118 |
|
119 |
function get_current_tag() {
|
120 |
global $json_api;
|
121 |
-
|
122 |
-
|
123 |
-
|
|
|
124 |
}
|
125 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
}
|
127 |
|
128 |
function get_authors() {
|
129 |
global $wpdb;
|
130 |
-
$author_ids = $wpdb->get_col($wpdb->prepare("
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
131 |
$all_authors = array_map(array(&$this, 'get_author'), $author_ids);
|
132 |
$active_authors = array_filter($all_authors, array(&$this, 'is_active_author'));
|
133 |
return $active_authors;
|
@@ -145,8 +154,9 @@ class JSON_API_Introspector {
|
|
145 |
function is_active_author($author) {
|
146 |
if (!isset($this->active_authors)) {
|
147 |
$this->active_authors = explode(',', wp_list_authors('html=0&echo=0'));
|
|
|
148 |
}
|
149 |
-
return in_array($author->
|
150 |
}
|
151 |
|
152 |
function set_posts_query($query = '') {
|
69 |
if ($wp_category->term_id == 1 && $wp_category->slug == 'uncategorized') {
|
70 |
continue;
|
71 |
}
|
72 |
+
$categories[] = $this->get_category_object($wp_category);
|
73 |
}
|
74 |
return $categories;
|
75 |
}
|
76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
function get_current_category() {
|
78 |
global $json_api;
|
79 |
+
if (!empty($json_api->query->category_id)) {
|
80 |
+
return $this->get_category_by_id($json_api->query->category_id);
|
81 |
+
} else if (!empty($json_api->query->category_slug)) {
|
82 |
+
return $this->get_category_by_slug($json_api->query->category_slug);
|
83 |
}
|
84 |
+
return null;
|
85 |
+
}
|
86 |
+
|
87 |
+
function get_category_object($wp_category) {
|
88 |
+
return new JSON_API_Category($wp_category);
|
89 |
+
}
|
90 |
+
|
91 |
+
function get_category_by_id($category_id) {
|
92 |
+
$wp_category = get_term_by('id', $category_id, 'category');
|
93 |
+
return $this->get_category_object($wp_category);
|
94 |
+
}
|
95 |
+
|
96 |
+
function get_category_by_slug($category_slug) {
|
97 |
+
$wp_category = get_term_by('slug', $category_slug, 'category');
|
98 |
+
return $this->get_category_object($wp_category);
|
99 |
}
|
100 |
|
101 |
function get_tags() {
|
102 |
$wp_tags = get_tags();
|
103 |
+
return array_map(array(&$this, 'get_tag_object'), $wp_tags);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
}
|
105 |
|
106 |
function get_current_tag() {
|
107 |
global $json_api;
|
108 |
+
if (!empty($json_api->query->tag_id)) {
|
109 |
+
return $this->get_tag_by_id($json_api->query->tag_id);
|
110 |
+
} else if (!empty($json_api->query->tag_slug)) {
|
111 |
+
return $this->get_tag_by_slug($json_api->query->tag_slug);
|
112 |
}
|
113 |
+
return null;
|
114 |
+
}
|
115 |
+
|
116 |
+
function get_tag_object($wp_tag) {
|
117 |
+
return new JSON_API_Tag($wp_tag);
|
118 |
+
}
|
119 |
+
|
120 |
+
function get_tag_by_id($tag_id) {
|
121 |
+
$wp_tag = get_term_by('id', $tag_id, 'post_tag');
|
122 |
+
return $this->get_tag_object($wp_tag);
|
123 |
+
}
|
124 |
+
|
125 |
+
function get_tag_by_slug($tag_slug) {
|
126 |
+
$wp_tag = get_term_by('slug', $tag_slug, 'post_tag');
|
127 |
+
return $this->get_tag_object($wp_tag);
|
128 |
}
|
129 |
|
130 |
function get_authors() {
|
131 |
global $wpdb;
|
132 |
+
$author_ids = $wpdb->get_col($wpdb->prepare("
|
133 |
+
SELECT u.ID, m.meta_value AS last_name
|
134 |
+
FROM $wpdb->users AS u,
|
135 |
+
$wpdb->usermeta AS m
|
136 |
+
WHERE m.user_id = u.ID
|
137 |
+
AND m.meta_key = 'last_name'
|
138 |
+
ORDER BY last_name
|
139 |
+
"));
|
140 |
$all_authors = array_map(array(&$this, 'get_author'), $author_ids);
|
141 |
$active_authors = array_filter($all_authors, array(&$this, 'is_active_author'));
|
142 |
return $active_authors;
|
154 |
function is_active_author($author) {
|
155 |
if (!isset($this->active_authors)) {
|
156 |
$this->active_authors = explode(',', wp_list_authors('html=0&echo=0'));
|
157 |
+
$this->active_authors = array_map('trim', $this->active_authors);
|
158 |
}
|
159 |
+
return in_array($author->name, $this->active_authors);
|
160 |
}
|
161 |
|
162 |
function set_posts_query($query = '') {
|
singletons/query.php
CHANGED
@@ -152,5 +152,5 @@ class JSON_API_Query {
|
|
152 |
return 'error';
|
153 |
}
|
154 |
}
|
155 |
-
|
156 |
}
|
152 |
return 'error';
|
153 |
}
|
154 |
}
|
155 |
+
|
156 |
}
|
singletons/response.php
CHANGED
@@ -21,6 +21,7 @@ class JSON_API_Response {
|
|
21 |
global $wp_query;
|
22 |
return $this->get_json(array(
|
23 |
'count' => count($posts),
|
|
|
24 |
'pages' => $wp_query->max_num_pages,
|
25 |
'posts' => $posts
|
26 |
), $status);
|
@@ -46,6 +47,8 @@ class JSON_API_Response {
|
|
46 |
$data = array_merge(array('status' => $status), $data);
|
47 |
}
|
48 |
|
|
|
|
|
49 |
if (!empty($_REQUEST['dev'])) {
|
50 |
// Don't JSON encode the data in dev mode
|
51 |
return $data;
|
@@ -54,8 +57,10 @@ class JSON_API_Response {
|
|
54 |
return json_encode($data);
|
55 |
} else {
|
56 |
// Use PEAR's Services_JSON encoder otherwise
|
57 |
-
|
58 |
-
|
|
|
|
|
59 |
$json = new Services_JSON();
|
60 |
return $json->encode($data);
|
61 |
}
|
21 |
global $wp_query;
|
22 |
return $this->get_json(array(
|
23 |
'count' => count($posts),
|
24 |
+
'count_total' => $wp_query->found_posts,
|
25 |
'pages' => $wp_query->max_num_pages,
|
26 |
'posts' => $posts
|
27 |
), $status);
|
47 |
$data = array_merge(array('status' => $status), $data);
|
48 |
}
|
49 |
|
50 |
+
$data = apply_filters('json_api_encode', $data);
|
51 |
+
|
52 |
if (!empty($_REQUEST['dev'])) {
|
53 |
// Don't JSON encode the data in dev mode
|
54 |
return $data;
|
57 |
return json_encode($data);
|
58 |
} else {
|
59 |
// Use PEAR's Services_JSON encoder otherwise
|
60 |
+
if (!class_exists('Services_JSON')) {
|
61 |
+
global $json_api_dir;
|
62 |
+
require_once "$json_api_dir/library/JSON.php";
|
63 |
+
}
|
64 |
$json = new Services_JSON();
|
65 |
return $json->encode($data);
|
66 |
}
|