This tutorial walks you through creating a custom WP-API endpoint. We’ll first create a child theme of the default “Twenty Seventeen” theme, which will allow us to add functionality to our theme, and then proceed to register our custom API endpoint.
The WordPress REST API provides you with more than just a set of built-in routes. You can also create custom routes and endpoints using the same APIs used to create default routes (for example, the register_rest_route()
function and the WP_Rest_Controller
class etc.). With WP-API, you’ll have the possibility to integrate WordPress with other ecosystems, which makes WordPress a powerful and modern application development platform.
You can create or register custom endpoints either in plugins or themes.
Creating a Child Theme
Inside your WordPress installation folder, create a folder for your child theme. Let’s call it twentyseventeen-child
:
cd /var/www/html/wp-content/themes
mkdir twentyseventeen-child
Next create a style.css
file:
touch style.css
And add the following header information:
/*
Theme Name: Twenty Seventeen Child Theme
description: A child theme of the Twenty Seventeen WordPress theme
Author: Ahmed Bouchefra
Template: twentyseventeen
Version: 1.0.0
*/
The Template field refers to the folder’s name of the parent theme.
Go to Appearance -> Themes in the WordPress admin and choose your child theme:
Next, click on the Activate button to activate your child theme:
Inside the theme folder, add a functions.php
file with the following initial code:
<?php
// Add code here.
Creating a Custom WP-API Endpoint
We want to create a new route that will allow us to retrieve the latest recent posts by category ID with the following format:
http://localhost/wp-json/mytwentyseventeentheme/v1/latest-posts/<CATEGORY_ID>
At this point, if we visit the above URL in our browser we’ll get a 404 error with the message “No route was found matching the URL and request method”:
This is because we don’t actually have that route. Let’s change that!
In the functions.php
file of your theme, add the following code:
add_action('rest_api_init', function () {
register_rest_route( 'mytwentyseventeentheme/v1', 'latest-posts/(?P<category_id>\d+)',array(
'methods' => 'GET',
'callback' => 'get_latest_posts_by_category'
));
});
We’re using the register_rest_route()
with the following parameters:
- a namespace,
mytwentyseventeentheme/v1
- a resource path with a regex for catching the category ID,
latest-posts/(?P<category_id>\d+)
- an option array where we specify the GET method and a
get_latest_posts_by_category()
callback function that handles the request.
A namespace allows two plugins or themes to use the same route paths without conflict and the clients to detect the support for your custom API by simply using the /wp-json/wp/v2
API and checking the namespaces field.
You can see from the screenshot, the mytwentyseventeentheme/v1
namespace we used for our custom route is added to the namespaces field (this screenshot is taken after we fully implement our custom endpoint; please continue below).
Notice the ?P<category_id>\d+
part. It will enable us to retrieve the category ID from the current request. It’s simply a regex, so you can use normal regex logic to create any pattern.
Implementing the Callback Function
At this point, if we visit our previous URL, WordPress recognizes the route, since we’ve defined it. But we still get a 500 error with the “The handler for the route is invalid” message.
After registering the custom route and specifying the get_latest_posts_by_category()
function as the callback that will be called for processing and handling the GET request, let’s actually implement it:
function get_latest_posts_by_category($request) {
$args = array(
'category' => $request['category_id']
);
$posts = get_posts($args);
if (empty($posts)) {
return new WP_Error( 'empty_category', 'there is no post in this category', array('status' => 404) );
}
$response = new WP_REST_Response($posts);
$response->set_status(200);
return $response;
}
We first retrieve the category_id
argument from the $request
parameter by direct access. Next we create an $args
array with the category
key set to the value of category_id
that will be extracted from the route.
We then call the get_posts()
method to query for posts with the specified category ID. If we get an empty posts array, we return an error message comprised of an empy_category
code, a there is no post in this category
message and 404 status code — all of which are passed to the constructor of the WP_Error
class.
This is a screenshot we get if we have an empty category:
We finally create a new instance of the WP_REST_Response
class; we pass in the $posts
array; we set the 200 status code; and we return the REST response. We can also directly return the $posts
array and it will be automatically converted to JSON.
The WP_Error
and WP_REST_Response
classes are used to make sure that the endpoint returns a valid JSON response.
Now, if we return to our browser and visit for example this URL:
http://<YOUR_SITE_DOMAIN>/wp-json/mytwentyseventeentheme/v1/latest-posts/1
… we’ll either get an empty array or the posts belonging to the category of ID 1.
You can also provide sanitization and validation callbacks in addition to your main callback.
You can define arguments for each route as an array with the args
option just like the callback
option. In the array, you can add multiple arguments. The key is the name of the argument and the value is an array of options for that argument, such as sanitize_callback
or validate_callback
.
validate_callback
is a callback function to validate the argument. It takes a function that will be passed the value of the argument and should return true if the value is valid or false otherwise.sanitize_callback
is a callback function used for sanitizing the value of the argument before passing it to the maincallback
function. The value is passed as a parameter to this function.
The post Creating Custom Endpoints for the WordPress REST API appeared first on SitePoint.
No comments:
Post a Comment