Creating Custom WordPress API Endpoints with Meta Filters

The WordPress REST API provides a simple and convenient way to access the data stored in a WordPress site. However, in some cases, you may need to create a custom endpoint that allows you to retrieve specific data based on specific criteria. In this blog post, we will walk you through the process of creating a custom WordPress API endpoint that enables you to filter posts based on an unlimited number of meta keys and values, with pagination support.

First, let’s create a new plugin for our custom endpoint. To do this, create a new folder in the wp-content/plugins directory and name it custom-api-endpoint. Next, create a new file in the folder and name it custom-api-endpoint.php.

In the custom-api-endpoint.php file, add the following code:

<?php
/*
Plugin Name: Custom API Endpoint
Description: A custom API endpoint for filtering posts based on meta keys and values with pagination support.
Version: 1.0
Author: Your Name
*/

function custom_api_endpoint_init() {
    register_rest_route( 'custom/v1', '/posts', array(
        'methods' => 'GET',
        'callback' => 'custom_api_endpoint_posts',
    ) );
}
add_action( 'rest_api_init', 'custom_api_endpoint_init' );

function custom_api_endpoint_posts( $request ) {
    $meta_query = array();
    $meta_key = $request->get_param( 'meta_key' );
    $meta_value = $request->get_param( 'meta_value' );

    if ( $meta_key && $meta_value ) {
        $meta_query[] = array(
            'key' => $meta_key,
            'value' => $meta_value,
        );
    }

    $args = array(
        'post_type' => 'post',
        'meta_query' => $meta_query,
        'paged' => $request->get_param( 'page' ),
        'posts_per_page' => $request->get_param( 'per_page' ),
    );
    $posts = new WP_Query( $args );

    $data = array();
    while ( $posts->have_posts() ) {
        $posts->the_post();
        $data[] = array(
            'id' => get_the_ID(),
            'title' => get_the_title(),
            'content' => get_the_content(),
        );
    }

    return rest_ensure_response( $data );
}

 

In this code, we have defined a custom endpoint using the register_rest_route function. The endpoint is located at /custom/v1/posts and can be accessed via the GET method. The custom_api_endpoint_posts function is used as the callback for the endpoint.

In the custom_api_endpoint_posts function, we retrieve the values of the meta_key and meta_value parameters from the request object. These parameters are used to filter the posts based on the meta key and value. We then use the WP_Query class to retrieve the posts that match the criteria. The returned data includes the ID, title, and content of each post.

To allow for unlimited meta keys and values, we can modify the code as follows:

// Callback function for the custom endpoint
function custom_api_endpoint_posts( $request ) {
    $meta_query = array();
    $meta_keys = $request->get_param( 'meta_keys' );
    $meta_values = $request->get_param( 'meta_values' );

    // If both meta_keys and meta_values are present, create the meta_query array
    if ( $meta_keys && $meta_values ) {
        // Explode the comma-separated strings into arrays
        $meta_keys = explode( ',', $meta_keys );
        $meta_values = explode( ',', $meta_values );

        // Loop through the meta keys and values, creating an entry in the meta_query array for each pair
        foreach ( $meta_keys as $key => $value ) {
            $meta_query[] = array(
                'key' => $value,
                'value' => $meta_values[$key],
            );
        }
    }

    // Set up the WP_Query arguments
    $args = array(
        'post_type' => 'post',
        'meta_query' => $meta_query,
        'paged' => $request->get_param( 'page' ),
        'posts_per_page' => $request->get_param( 'per_page' ),
    );

    // Execute the WP_Query
    $posts = new WP_Query( $args );

    // Retrieve the post data
    $data = array();
    while ( $posts->have_posts() ) {
        $posts->the_post();
        $data[] = array(
            'id' => get_the_ID(),
            'title' => get_the_title(),
            'content' => get_the_content(),
        );
    }

    // Return the post data as a JSON response
    return rest_ensure_response( $data );
}

 

In this updated code, instead of using a single meta_key and meta_value, we use two parameters, meta_keys and meta_values, which allow for multiple meta keys and values. The meta_keys and meta_values parameters are passed as comma-separated strings, which we then explode into arrays. We then loop through each value and create a new entry in the $meta_query array with the corresponding meta key and value.

With these changes, we can now pass multiple meta keys and values to the endpoint and retrieve posts based on multiple criteria. For example, to retrieve posts that have a featured meta key with a value of yes and a category meta key with a value of news, we can make a GET request to /custom/v1/posts?meta_keys=featured,category&meta_values=yes,news.

Finally, to support pagination, we can pass the page and per_page parameters to the endpoint. The page parameter specifies the page number, and the per_page parameter specifies the number of posts to retrieve per page. For example, to retrieve the second page of posts with 10 posts per page, we can make a GET request to /custom/v1/posts?meta_keys=featured,category&meta_values=yes,news&page=2&per_page=10.

In conclusion, creating a custom WordPress API endpoint is a simple and convenient way to retrieve specific data based on specific criteria. By allowing for unlimited meta keys and values and supporting pagination, you can create highly customized and flexible API endpoints that meet your specific needs.