JSON API - Version 0.7

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 Icon wp plugin JSON API
Version 0.7
Comparing to
See all releases

Code changes from version 0.5 to 0.7

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.5
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.6
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 website 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. This plugin provides the necessary interface for retrieving content and accepting comment submissions.
13
 
14
- The current release (0.5) 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,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
- 2. *Explicit mode* is triggered by setting `json` to a known method string. See the API Reference section below for a complete method listing.
36
 
37
- == Example requests ==
38
-
39
- Implicit mode:
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
- You can also use a different URL syntax for explicit-mode requests if your weblog is configured to use `mod_rewrite` for permalinks:
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. For more information about the JSON format, see http://json.org/.
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
- This section describes data objects you can retrieve from WordPress as well as the behavior of URL redirects.
145
 
146
- __Status values__
147
 
148
- All API requests will result in a status value. The basic values are `ok` and `error`. For certain data manipulation methods, additional status values are available (such as `pending` in the case of a comment submission). Each API method listed below includes its possible status values.
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
- __Post response object__
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
- __Category response object__
174
 
175
  * `id` - Integer
176
  * `slug` - String
@@ -179,14 +174,15 @@ __Category response object__
179
  * `parent` - Integer
180
  * `post_count` - Integer
181
 
182
- __Tag response object__
183
 
184
  * `id` - Integer
185
  * `slug` - String
186
  * `title` - String
187
  * `description` - String
 
188
 
189
- __Author response object__
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
- __Comment response object__
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
- __Redirects__
 
 
213
 
214
- Setting the `redirect` argument to `http://www.example.com/foo` will result in one of the following URLs depending on the resulting status value:
215
 
216
  * `http://www.example.com/foo?status=ok`
217
  * `http://www.example.com/foo?status=error`
218
 
219
- You can alternatively set `redirect_ok` to `http://www.example.com/handle_ok` and `redirect_error` to `http://www.example.com/handle_error` to have more control over the redirect behavior.
 
 
 
 
220
 
221
- == 3. Introspection methods ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
 
223
  Introspection methods are used to retrieve data from WordPress.
224
 
225
 
226
- __Method: `get_recent_posts`__
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 format:
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 format:
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 format:
280
 
281
  {
282
  "status": "ok",
283
  "page": { ... }
284
  }
285
 
286
- Status values: `ok`, `error`
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 format:
303
 
304
  {
305
  "status": "ok",
306
  "count": 10,
 
307
  "pages": 7,
308
  "posts": [
309
  { ... },
@@ -312,28 +332,26 @@ Response format:
312
  ]
313
  }
314
 
315
- Status values: `ok`, `error`
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 format:
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 format:
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
- __Method: `get_author_posts`__
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 format:
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
- __Method: `get_search_results`__
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 format:
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 format:
445
 
446
  {
447
  "status": "ok",
@@ -458,16 +471,14 @@ Response format:
458
  }
459
  }
460
 
461
- Note: the tree is arranged by [year] > [month] > [number of posts].
462
-
463
- Status values: `ok`, `error`
464
 
465
 
466
- __Method: `get_category_index`__
467
 
468
  Returns an array of active categories.
469
 
470
- Response format:
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 format:
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 format:
509
 
510
  {
511
  "status": "ok",
@@ -517,40 +524,48 @@ Response format:
517
  ]
518
  }
519
 
520
- Status values: `ok`, `error`
521
-
522
 
523
- == 4. Data manipulation methods ==
524
 
525
  Data manipulation methods are used for saving content back to WordPress.
526
 
527
- **Incomplete**
528
-
529
  The data manipulation methods are still very incomplete.
530
 
531
 
532
- __Method: `submit_comment`__
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` (comment pending review)
 
 
549
 
550
- Status values: `ok`, `error`, `pending`
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->get_category($wp_category);
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
- $category = $json_api->query->category_id;
94
- if (empty($category)) {
95
- $category = $json_api->query->category_slug;
 
96
  }
97
- return $this->get_category($category);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  }
99
 
100
  function get_tags() {
101
  $wp_tags = get_tags();
102
- return array_map(array(&$this, 'get_tag'), $wp_tags);
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
- $tag = $json_api->query->tag_id;
122
- if (empty($tag)) {
123
- $tag = $json_api->query->tag_slug;
 
124
  }
125
- return $this->get_tag($tag);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  }
127
 
128
  function get_authors() {
129
  global $wpdb;
130
- $author_ids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM $wpdb->users"));
 
 
 
 
 
 
 
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->slug, $this->active_authors);
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
- global $json_api_dir;
58
- require_once "$json_api_dir/library/JSON.php";
 
 
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
  }