1

I have created an opps custom post type and registered a custom API field of closed for it with the following code:

public function get_opp_state() {
    register_rest_field( 'opps', 'closed', array(
        'get_callback' => array( $this, 'get_opp_state_callback' ),
        'update_callback' => null,
        'schema' => null
    ));        
} 

public function get_opp_state_callback( $opp ) {  
    $oppDeadline = get_field( 'deadline', $opp[ 'id' ] ); 
    $today = date( 'Ymd' );
    $isClosed = $oppDeadline < $today; 
    return $isClosed;            
}                               

To retrieve all posts that use the opps post type, I use this request:

http://example.com/wp-json/wp/v2/opps

Now how can I extend that request to only fetch opps posts that have a closed field equal to true? I was hoping the following would work, but it doesn't:

http://example.com/wp-json/wp/v2/opps?closed=true

I know I can create a custom route, but I really would like to avoid that since the information returned by the default request has all the info I need (except for that closed field). So is there any way to achieve this without a custom route?

2

After a lot of digging I seem to have found a solution myself, and a pretty powerful one, which makes use of a rest_{ post_type }_query filter (replace the { post_type } part with the slug of your custom post type. You can use rest_post_query to alter the default /wp-json/wp/v2/posts request):

public function __construct() {  
    // Make sure you add those numbers at the end of the line, or it won't work
    add_filter( 'rest_opps_query', array( $this, 'get_opps_by_state' ), 10, 2 );  
}  

public function get_opps_by_state( $args, $request ) {

    $state = $request->get_param( 'state' );  

    if( $state == 'open' ) {
        $args[ 'meta_query' ] = array(
            'deadline' => array(
                'key' => 'deadline',
                'value' => date( 'Ymd' ), 
                'compare' => '>',
                'type' => 'DATE'
            )
        );
    } elseif ( $state == 'closed' ) {
        $args[ 'meta_query' ] = array(
            'deadline' => array(
                'key' => 'deadline',
                'value' => date( 'Ymd' ), 
                'compare' => '<',
                'type' => 'DATE'
            )
        );
    }

    return $args; 

}

So now I can use the default Wordpress API route to fetch custom posts:

http://example.com/wp-json/wp/v2/opps

and filter its results based on my custom parameter, status:

http://example.com/wp-json/wp/v2/opps?status=open

http://example.com/wp-json/wp/v2/opps?status=closed

No custom routes needed!

0

When modifying a REST request, you have 2 options, - register a field, like you have done, only adds a key:value pair to the json object. - register a meta, which allows the addition of a custom meta-field to the json object.

When you make a custom request with,

http://example.com/wp-json/wp/v2/pages?slug=my_page

for example, you are actually query a field of the post, in this case the slug.

When you do,

http://example.com/wp-json/wp/v2/opps?closed=true

you are attempting to query a field called closed which does not exists since it has only been added as a key and not a meta-field to the json response.

I think your best option is still a custom route

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.