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 Answers
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!