Skip to content

Commit

Permalink
Perform final sync from WXR
Browse files Browse the repository at this point in the history
  • Loading branch information
rmccue committed Nov 4, 2017
1 parent 8d18756 commit 46bd463
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 50 deletions.
8 changes: 7 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Changelog

This document details changes to the WP REST API since its public release in version 4.7.0.
## Version 4.8.1
<ul>
<li>Add a filter to allow modifying the response after embedded data is added. [#](https://core.trac.wordpress.org/changeset/41093)</li>
<li>`wp-api.js` client: Correctly interpret `settings` resource as a model rather than a collection. [#](https://core.trac.wordpress.org/changeset/41126)</li>
<li>Fix `PUT` (and other) requests for nginx servers by tweaking REST API URLs. [#](https://core.trac.wordpress.org/changeset/41140)</li>
</ul>
## Version 4.8.0
<ul>
<li>Improve strings added after 4.7.0 string freeze. [#](https://core.trac.wordpress.org/changeset/40571), [#](https://core.trac.wordpress.org/changeset/40606)</li>
Expand All @@ -12,7 +18,7 @@ This document details changes to the WP REST API since its public release in ver
<li>Add endpoint for proxying requests to external oEmbed providers, and use it in the media modal instead of the `parse-embed` AJAX action.  **This is the first usage of the WP REST API in `wp-admin`.** [#](http://core.trac.wordpress.org/changeset/40628)</li>
<li>Do not set `X-WP-Deprecated*` headers as often. [#](https://core.trac.wordpress.org/changeset/40782)</li>
<li>Avoid sending blank `Last-Modified` headers with authenticated requests. [#](https://core.trac.wordpress.org/changeset/40805)</li>
<li>Fix changing parameters with `$request-&gt;set_param()` for some requests. [#](https://core.trac.wordpress.org/changeset/40815)</li>
<li>Fix changing parameters with `$request->set_param()` for some requests. [#](https://core.trac.wordpress.org/changeset/40815)</li>
<li>In the admin area, ensure the REST API endpoint URL is forced to `https` when necessary. [#](https://core.trac.wordpress.org/changeset/40843)</li>
</ul>
## Version 4.7.4
Expand Down
37 changes: 19 additions & 18 deletions extending-the-rest-api/adding-custom-endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ add_action( 'rest_api_init', function () {
} );
```

Right now, we're only registering the one endpoint for the route. ("Route" is the URL, whereas "endpoint" is the function behind it that corresponds to a method *and* a URL. For more, see the [Glossary](/glossary.html).) If your site domain is `example.com` and you've kept the API path of `wp-json`, then the full URL would be `http://example.com/wp-json/myplugin/v1/author/(?P\d+)`. Each route can have any number of endpoints, and for each endpoint, you can define the HTTP methods allowed, a callback function for responding to the request and a permissions callback for creating custom permissions. In addition you can define allowed fields in the request and for each field specify a default value, a sanitization callback, a validation callback, and whether the field is required.
Right now, we're only registering the one endpoint for the route. The term "route" refers to the URL, whereas "endpoint" refers to the function behind it that corresponds to a method *and* a URL (for more information, see the [Glossary](https://developer.wordpress.org/rest-api/extending-the-rest-api/glossary/)).

For example, if your site domain is `example.com` and you've kept the API path of `wp-json`, then the full URL would be `http://example.com/wp-json/myplugin/v1/author/(?P\d+)`.

Each route can have any number of endpoints, and for each endpoint, you can define the HTTP methods allowed, a callback function for responding to the request and a permissions callback for creating custom permissions. In addition you can define allowed fields in the request and for each field specify a default value, a sanitization callback, a validation callback, and whether the field is required.


### Namespacing
Expand All @@ -54,7 +58,7 @@ Namespaces are the first part of the URL for the endpoint. They should be used a

Namespaces in general should follow the pattern of `vendor/v1`, where `vendor` is typically your plugin or theme slug, and `v1` represents the first version of the API. If you ever need to break compatibility with new endpoints, you can then bump this to `v2`.

The above scenario, two routes with the same name, from two different plugins, requires all vendors to use a unique namespace. Failing to do so is analagous to a failure to use a vendor function prefix, class prefix and/ or class namespace in a theme or plugin, which is very `_doing_it_wrong`.
The above scenario, two routes with the same name, from two different plugins, requires all vendors to use a unique namespace. Failing to do so is analogous to a failure to use a vendor function prefix, class prefix and/ or class namespace in a theme or plugin, which is **very very bad**.

An added benefit of using namespaces is that clients can detect support for your custom API. The API index lists out the available namespaces on a site:

Expand All @@ -72,8 +76,7 @@ An added benefit of using namespaces is that clients can detect support for your
}
```

If a client wants to check that your API exists on a site, they can check against this list. (For more information, see the [Discovery guide](/guide/discovery/).)

If a client wants to check that your API exists on a site, they can check against this list. (For more information, see the [Discovery guide](https://developer.wordpress.org/rest-api/using-the-rest-api/discovery/).)

### Arguments

Expand All @@ -83,23 +86,23 @@ By default, routes receive all arguments passed in from the request. These are m
<?php
function my_awesome_func( WP_REST_Request $request ) {
// You can access parameters via direct array access on the object:
$param = $request['some_param'];
$param = $request['some_param'];

// Or via the helper method:
$param = $request->get_param( 'some_param' );
$param = $request->get_param( 'some_param' );

// You can get the combined, merged set of parameters:
$parameters = $request->get_params();
$parameters = $request->get_params();

// The individual sets of parameters are also available, if needed:
$parameters = $request->get_url_params();
$parameters = $request->get_url_params();
$parameters = $request->get_query_params();
$parameters = $request->get_body_params();
$parameters = $request->get_json_params();
$parameters = $request->get_default_params();

// Uploads aren't merged in, but can be accessed separately:
$parameters = $request->get_file_params();
$parameters = $request->get_file_params();
}
```

Expand Down Expand Up @@ -206,7 +209,7 @@ When wrapping existing callbacks, you should always use `rest_ensure_response()`

You can also register a permissions callback for the endpoint. This is a function that checks if the user can perform the action (reading, updating, etc) before the real callback is called. This allows the API to tell the client what actions they can perform on a given URL without needing to attempt the request first.

This callback can be registered as `permission_callback`, again in the endpoint options next to your `callback` option. This callback should return a boolean or a `WP_Error` instance. If this function returns true, the response will be proccessed. If it returns false, a default error message will be returned and the request will not proceed with processing. If it returns a `WP_Error`, that error will be returned to the client.
This callback can be registered as `permission_callback`, again in the endpoint options next to your `callback` option. This callback should return a boolean or a `WP_Error` instance. If this function returns true, the response will be processed. If it returns false, a default error message will be returned and the request will not proceed with processing. If it returns a `WP_Error`, that error will be returned to the client.

The permissions callback is run after remote authentication, which sets the current user. This means you can use `current_user_can` to check if the user that has been authenticated has the appropriate capability for the action, or any other check based on current user ID. Where possible, you should always use `current_user_can`; instead of checking if the user is logged in (authentication), check whether they can perform the action (authorization).

Expand Down Expand Up @@ -320,7 +323,7 @@ class Slug_Custom_Route extends WP_REST_Controller {
*/
public function get_items( $request ) {
$items = array(); //do a query, call another class, etc
$data = array();
$data = array();
foreach( $items as $item ) {
$itemdata = $this->prepare_item_for_response( $item, $request );
$data[] = $this->prepare_response_for_collection( $itemdata );
Expand All @@ -337,14 +340,14 @@ class Slug_Custom_Route extends WP_REST_Controller {
*/
public function get_item( $request ) {
//get parameters from request
$params = $request->get_params();
$params = $request->get_params();
$item = array();//do a query, call another class, etc
$data = $this->prepare_item_for_response( $item, $request );
$data = $this->prepare_item_for_response( $item, $request );

//return a response or error based on some conditional
if ( 1 == 1 ) {
if ( 1 == 1 ) {
return new WP_REST_Response( $data, 200 );
}else{
} else {
return new WP_Error( 'code', __( 'message', 'text-domain' ) );
}
}
Expand All @@ -356,7 +359,6 @@ class Slug_Custom_Route extends WP_REST_Controller {
* @return WP_Error|WP_REST_Request
*/
public function create_item( $request ) {

$item = $this->prepare_item_for_database( $request );

if ( function_exists( 'slug_some_function_to_create_item') ) {
Expand Down Expand Up @@ -386,7 +388,6 @@ class Slug_Custom_Route extends WP_REST_Controller {
}

return new WP_Error( 'cant-update', __( 'message', 'text-domain'), array( 'status' => 500 ) );

}

/**
Expand Down Expand Up @@ -416,7 +417,7 @@ class Slug_Custom_Route extends WP_REST_Controller {
*/
public function get_items_permissions_check( $request ) {
//return true; <--use to make readable by all
return current_user_can( 'edit_something' );
return current_user_can( 'edit_something' );
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,8 @@ function my_book_taxonomy() {
}
```


## Adding REST API Support To Existing Content Types

When a custom post type or custom taxonomy has been added by code that you do not control, for example a theme or plugin you are using, you may need to add REST API support after it has alredy been registered. The arguments are the same as in the previous examples, but need to be added to the global `$wp_post_types` and `$wp_taxonomies` arrays.
When a custom post type or custom taxonomy has been added by code that you do not control, for example a theme or plugin you are using, you may need to add REST API support after it has already been registered. The arguments are the same as in the previous examples, but need to be added to the global `$wp_post_types` and `$wp_taxonomies` arrays.

Here is an example of adding REST API support to an existing custom post type:

Expand Down
2 changes: 1 addition & 1 deletion extending-the-rest-api/routes-and-endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ function prefix_register_product_routes() {
add_action( 'rest_api_init', 'prefix_register_product_routes' );
```

The above example covers a lot. The important part to note is that in the second route we register, we add on a path variable `/(?P[\d]+)` to our resource path `/products`. The path variable is a regular expression. In this case it uses `[\d]+` to signify that should be any numerical character at least once. If you are using numeric IDs for your resources, then this is a great example of how to use a path variable. When using path variables, we now have to be careful around what can be matched as it is user input.
The above example covers a lot. The important part to note is that in the second route we register, we add on a path variable `/(?P<id>[\d]+)` to our resource path `/products`. The path variable is a regular expression. In this case it uses `[\d]+` to signify that should be any numerical character at least once. If you are using numeric IDs for your resources, then this is a great example of how to use a path variable. When using path variables, we now have to be careful around what can be matched as it is user input.

The regex luckily will filter out anything that is not numerical. However, what if the product for the requested ID doesn't exist. We need to do error handling. You can see the basic way we are handling errors in the code example above. When you return a `WP_Error` in your endpoint callbacks the API server will automatically handle serving the error to the client.

Expand Down
3 changes: 1 addition & 2 deletions index.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ One of the primary classes in the  WordPress REST API infrastructure is `WP_RES

### Responses

Responses are the data you get back from the API. The `WP_REST_Response` provides a way to interact with the response data returned by endpoints. Responses can return the desired data, and they can also be used to return errors.

Responses are the data you get back from the API. The `WP_REST_Response` class provides a way to interact with the response data returned by endpoints. Responses can return the desired data, and they can also be used to return errors.

### Schema

Expand Down
2 changes: 1 addition & 1 deletion requests.md
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ function prefix_validate_requests( $requests, $request, $param_key ) {
return new WP_Error( 'rest_invald_param', esc_html__( 'You must specify the method and route for each request.' ), array( 'status' => 400 ) );
}

if ( isset( $request['params'] ) &amp;&amp; ! is_array( $request['params'] ) ) {
if ( isset( $request['params'] ) && ! is_array( $request['params'] ) ) {
return new WP_Error( 'rest_invald_param', esc_html__( 'You must specify the params for each request as an array of named key value pairs.' ), array( 'status' => 400 ) );
}
}
Expand Down
2 changes: 1 addition & 1 deletion using-the-rest-api/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ While cookie authentication is the only authentication mechanism available nativ

[info]

There's also a <a href="https://github.com/WP-API/Basic-Auth">Basic Authentication</a> plugin.
There's also a [Basic Authentication](https://github.com/WP-API/Basic-Auth) plugin.

Note that this plugin requires sending your username and password with every request, and should only be used for development and testing i.e. not in a production environment.

Expand Down
44 changes: 21 additions & 23 deletions using-the-rest-api/backbone-javascript-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Models:
* Tag
* Taxonomy
* Type
* User`
* User

Collections:
* Categories
Expand Down Expand Up @@ -139,66 +139,64 @@ post.fetch();
// Get a collection of the post's categories (returns a promise)
// Uses _embedded data if available, in which case promise resolves immediately.
post.getCategories().done( function( postCategories ) {
// ... do something with the categories.
// The new post has an single Category: Uncategorized
console.log( postCategories[0].name );
// response -> "Uncategorized"
// ... do something with the categories.
// The new post has an single Category: Uncategorized
console.log( postCategories[0].name );
// response -> "Uncategorized"
} );

// Get a posts author User model.
post.getAuthorUser().done( function( user ){
// ... do something with user
console.log( user.get( 'name' ) );
// ... do something with user
console.log( user.get( "name" ) );
} );

// Get a posts featured image Media model.
post.getFeaturedImage().done( function( image ){
// ... do something with image
console.log( image );
// ... do something with image
console.log( image );
} );

// Set the post categories.
post.setCategories( [ 'apples', 'oranges' ] );
post.setCategories( [ "apples", "oranges" ] );

// Get all the categories
var allCategories = new wp.api.collections.Categories()
allCategories.fetch();

var appleCategory = allCategories.findWhere( { slug: 'apples' } );
var appleCategory = allCategories.findWhere( { slug: "apples" } );

// Add the category to the postCategories collection we previously fetched.
appleCategory.set( 'parent_post', post.get( 'id' ) );
appleCategory.set( "parent_post", post.get( "id" ) );

// Use the POST method so Backbone will not PUT it even though it has an id.
postCategories.create( appleCategory.toJSON(), { type: 'POST' } );
postCategories.create( appleCategory.toJSON(), { type: "POST" } );

// Remove the Uncategorized category
postCategories.at( 0 ).destroy();

// Check the results - re-fetch
postCategories = post.getCategories();

postCategories.at( 0 ).get( 'name' );
postCategories.at( 0 ).get( "name" );
// response -> "apples"
```


### Collection examples:

to get the last 10 posts:
To get the last 10 posts:

```js
var postsCollection = new wp.api.collections.Posts();
postsCollection.fetch();
```

to get the last 25 posts:
To get the last 25 posts:

```js
postsCollection.fetch( { data: { per_page: 25 } } );
```

use filter to change the order & orderby options:
Use filter to change the order & orderby options:

```js
postsCollection.fetch( { data: { 'filter': { 'orderby': 'title', 'order': 'ASC' } } } );
Expand All @@ -210,13 +208,13 @@ All collections support pagination automatically, and you can get the next page
postsCollection.more();
```

to get page 5 of a collection:
To get page 5 of a collection:

```js
posts.fetch( { data: { page: 5 } } );
```

check if the collection has any more posts:
Check if the collection has any more posts:

```js
posts.hasMore();
Expand All @@ -239,8 +237,8 @@ Revision collections can also be accessed via their parent's collection. This ex
var post = new wp.api.models.Post( { id: 1 } );
post.fetch();
post.getRevisions().done( function( revisions ){
console.log( revisions );
console.log( revisions );
});
```

If you add custom endpoints to the api they will also become available as models/collections. For example, you will get new models and collections when you [add REST API support to your custom post type](http://v2.wp-api.org/extending/custom-content-types/). Note: because the schema is stored in the user's session cache to avoid re-fetching, you may need to open a new tab to get a new read of the Schema.
If you add custom endpoints to the API they will also become available as models/collections. For example, you will get new models and collections when you [add REST API support to your custom post type](http://v2.wp-api.org/extending/custom-content-types/). Note: Because the schema is stored in the user's session cache to avoid re-fetching, you may need to open a new tab to get a new read of the Schema.

0 comments on commit 46bd463

Please sign in to comment.