As the REST API is still relatively new there might be some endpoints that don't currently exist such as getting the post archives where you would normally use the function wp_get_archives. This function will return a list of months with the post count next to that month. In this tutorial we're going to create our own WordPress endpoint that returns a list of months along with the post count with that month.
First Create A WordPress Plugin
To create a WordPress plugin you just need to create a file inside the plugins folder and add the following comments to the top of the file.
/**
* Plugin Name: Paulund REST Post Archives
* Plugin URI: https://paulund.co.uk
* Description: Plugin to create a new restful endpoint to get month post archives
* Version: 1.0
* Author: Paulund
* Author URI: https://paulund.co.uk
* Text Domain: paulund
*/
Create The PHP Class
All the plugins I create use PHP OOP this is because I find it easier to organise and handle the code. The first thing we need to create is the PHP class and the run method to start the plugin.
/**
* Rest API Post Archives list
*/
class Rest_Post_Archives
{
/**
* Run WordPress filters
*/
public function run()
{
}
}
$restPostArchives = new Rest_Post_Archives();
$restPostArchives->run();
The run()
method is where we'll add any WordPress actions or filters we need to use. In this plugin we need to use the WordPress action rest_api_init
which runs at the start of the REST API.
Register The Endpoint
To create a new Endpoint on your WordPress REST API you need to use the function register_rest_route. This accepts 4 parameters namespace, route, args and override. We're going to create a new endpoint with the route of posts/archives
to return a list of months with the post count.
add_action( 'rest_api_init', function () {
register_rest_route( 'wp/v2', '/posts/archives', array(
'methods' => 'GET',
'callback' => array($this, 'get_rest_post_archives'),
) );
} );
We now have a new endpoint that we can access with the URL http://example.com/wp-json/wp/v2/posts/archives
.
Get The Rest Post Archives
Inside the registered route function we're using a callback of get_rest_post_archives
this is the function we use to get the months and the post type within these months.
/**
* Get the post archives from rest api
*
* @param $request
*
* @return mixed|\WP_REST_Response
*/
public function get_rest_post_archives( $request )
{
global $wpdb;
$defaults = array(
'type' => 'monthly', 'limit' => '',
'format' => 'html', 'before' => '',
'after' => '', 'show_post_count' => false,
'echo' => 1, 'order' => 'DESC',
'post_type' => 'post'
);
$r = wp_parse_args( $request, $defaults );
$post_type_object = get_post_type_object( $r['post_type'] );
if ( ! is_post_type_viewable( $post_type_object ) ) {
return;
}
$r['post_type'] = $post_type_object->name;
if ( '' == $r['type'] ) {
$r['type'] = 'monthly';
}
if ( ! empty( $r['limit'] ) ) {
$r['limit'] = absint( $r['limit'] );
$r['limit'] = ' LIMIT ' . $r['limit'];
}
$order = strtoupper( $r['order'] );
if ( $order !== 'ASC' ) {
$order = 'DESC';
}
$sql_where = $wpdb->prepare( "WHERE post_type = %s AND post_status = 'publish'", $r['post_type'] );
/**
* Filters the SQL WHERE clause for retrieving archives.
*
* @since 2.2.0
*
* @param string $sql_where Portion of SQL query containing the WHERE clause.
* @param array $r An array of default arguments.
*/
$where = apply_filters( 'getarchives_where', $sql_where, $r );
/**
* Filters the SQL JOIN clause for retrieving archives.
*
* @since 2.2.0
*
* @param string $sql_join Portion of SQL query containing JOIN clause.
* @param array $r An array of default arguments.
*/
$join = apply_filters( 'getarchives_join', '', $r );
$last_changed = wp_cache_get_last_changed( 'posts' );
$limit = $r['limit'];
$query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date $order $limit";
$key = md5( $query );
$key = "wp_get_archives:$key:$last_changed";
if ( ! $results = wp_cache_get( $key, 'posts' ) ) {
$results = $wpdb->get_results( $query );
wp_cache_set( $key, $results, 'posts' );
}
return rest_ensure_response( $results );
}
This code was taken from the function wp_get_archives and I've taken out the bits that we don't need like changing the type as we only want to work with months post count. ## Results
When the plugin is installed you'll have the new endpoint registered which you can access by navigating to /wp-json/wp/v2/posts/archives
this will return a JSON of the months and post count.
[{
"year": "2016",
"month": "9",
"posts": "10"
}, {
"year": "2016",
"month": "8",
"posts": "3"
}, {
"year": "2016",
"month": "7",
"posts": "6"
}, {
"year": "2016",
"month": "6",
"posts": "2"
}, {
"year": "2016",
"month": "5",
"posts": "12"
}, {
"year": "2016",
"month": "4",
"posts": "7"
}, {
"year": "2016",
"month": "3",
"posts": "6"
}, {
"year": "2016",
"month": "2",
"posts": "5"
}, {
"year": "2016",
"month": "1",
"posts": "4"
}]