I have two Custom post types: question and answer. "Questions" are hierarchical and they are parent posts for answers - which are child posts. For every answer, there's a parent question. When someone asks a question, every answer given is correctly attributed to the same question. This has already been nicely done in the website. While I am building the APP, I can pull in all questions, but when it comes to answers, I can't seem to filter out answer by parent question.
All questions can be obtained like this:
For answers, I am using custom endpoint with this code:
add_action( 'rest_api_init', 'custom_api_get_all_posts' );
function custom_api_get_all_posts() {
register_rest_route( 'app/v1', '/answers', array(
'methods' => 'GET',
'callback' => 'custom_api_get_all_posts_callback'
));
}
function custom_api_get_all_posts_callback( $request ) {
// Initialize the array that will receive the posts' data.
$posts_data = array();
// Receive and set the page parameter from the $request for pagination purposes
$paged = $request->get_param( 'page' );
$paged = ( isset( $paged ) || ! ( empty( $paged ) ) ) ? $paged : 1;
// Get the posts using the 'post' and 'news' post types
// $avatar_url = get_avatar_url ( get_the_author_meta('ID'), $size = '50' );
$posts = get_posts( array(
'paged' => $paged,
'posts_per_page' => 10,
'post_type' => 'answer',
));
if ( is_array( $filter ) && array_key_exists( 'question', $filter ) ) {
$args['post_parent_id'] = $filter['question'];
}
// Loop through the posts and push the desired data to the array we've initialized earlier in the form of an object
foreach( $posts as $post ) {
$id = $post->ID;
$posts_data[] = (object) array(
'id' => $id,
'slug' => $post->post_name,
'type' => $post->post_type,
'title' => $post->post_title,
'content' => $post->post_content,
'question' => $post->post_parent,
);
}
return $posts_data;
}
And by this, I can get all answers with their IDs, Answer Title, Content, and Parent Question Id in GET response at
QUESTION: How do I have to modify the code to be able to filter out specific answers based on question ID, something like: where 1234 is an ID for a parent question whose answers we need to display. All suggested filter plugins have failed to work, I've tried different forms of codes for so many hours, I really appreciate your help :)
Thanks! (Both question and answer are CPTs, and I am using WP Version - 4.9.8)
I have two Custom post types: question and answer. "Questions" are hierarchical and they are parent posts for answers - which are child posts. For every answer, there's a parent question. When someone asks a question, every answer given is correctly attributed to the same question. This has already been nicely done in the website. While I am building the APP, I can pull in all questions, but when it comes to answers, I can't seem to filter out answer by parent question.
All questions can be obtained like this: https://domain/wp-json/wp/v2/questions
For answers, I am using custom endpoint with this code:
add_action( 'rest_api_init', 'custom_api_get_all_posts' );
function custom_api_get_all_posts() {
register_rest_route( 'app/v1', '/answers', array(
'methods' => 'GET',
'callback' => 'custom_api_get_all_posts_callback'
));
}
function custom_api_get_all_posts_callback( $request ) {
// Initialize the array that will receive the posts' data.
$posts_data = array();
// Receive and set the page parameter from the $request for pagination purposes
$paged = $request->get_param( 'page' );
$paged = ( isset( $paged ) || ! ( empty( $paged ) ) ) ? $paged : 1;
// Get the posts using the 'post' and 'news' post types
// $avatar_url = get_avatar_url ( get_the_author_meta('ID'), $size = '50' );
$posts = get_posts( array(
'paged' => $paged,
'posts_per_page' => 10,
'post_type' => 'answer',
));
if ( is_array( $filter ) && array_key_exists( 'question', $filter ) ) {
$args['post_parent_id'] = $filter['question'];
}
// Loop through the posts and push the desired data to the array we've initialized earlier in the form of an object
foreach( $posts as $post ) {
$id = $post->ID;
$posts_data[] = (object) array(
'id' => $id,
'slug' => $post->post_name,
'type' => $post->post_type,
'title' => $post->post_title,
'content' => $post->post_content,
'question' => $post->post_parent,
);
}
return $posts_data;
}
And by this, I can get all answers with their IDs, Answer Title, Content, and Parent Question Id in GET response at https://domain/wp-json/app/v1/answers
QUESTION: How do I have to modify the code to be able to filter out specific answers based on question ID, something like: https://domain/wp-json/app/v1/answers?question=1234 where 1234 is an ID for a parent question whose answers we need to display. All suggested filter plugins have failed to work, I've tried different forms of codes for so many hours, I really appreciate your help :)
Thanks! (Both question and answer are CPTs, and I am using WP Version - 4.9.8)
Share Improve this question edited Nov 5, 2018 at 2:26 Nisse Engström 1151 silver badge2 bronze badges asked Nov 4, 2018 at 23:52 B.DerB.Der 14 bronze badges2 Answers
Reset to default 0I'd start out by checking that your request is being passed properly. I'd do that by changing this:
function custom_api_get_all_posts_callback( $request ) {
// Initialize the array that will receive the posts' data.
$posts_data = array();
to this:
function custom_api_get_all_posts_callback( $request ) {
// Initialize the array that will receive the posts' data.
echo "<pre>";
print_r( $request );
echo "</pre>";
$posts_data = array();
... and then calling the page as you do: https://domain/wp-json/app/v1/answers?question=1234
Then you should be able to see your request.
It looks like that your code is returning a list of posts. But if you then add a check in the top saying (if id
is specified, then return just a single post). It would look something like this:
if( $request->get_param( 'id' ) ):
// Find that page and return just that.
endif;
The Question was about filtering out child posts by parent posts, both of which are custom post types in wordpress. This is how I did it, works great.
You can add this code in your own simple plugin: (Just create a new folder under plugins, add this code to index.php, ensure to enclose the code between <?php //code here, with a proper plugin header; ?>
and activate the plugin.
add_action( 'rest_api_init', 'custom_api_get_all_posts' );
function custom_api_get_all_posts() {
//let's register our custom route here
register_rest_route( 'wp/v2', '/answers/question=(?P<post_parent>\d+)&page=(?P<page>\d+)', array(
'methods' => 'GET',
'callback' => 'answers_by_parent_id_callback',
'args' => [
'post_parent',
'page'
],
));
}
//here we define our callback function
function answers_by_parent_id_callback( $request ) {
//let's initialize our data array
$posts_data = array();
// Receive and set the page parameter from the $request for pagination
$paged = $request->get_param( 'page' );
$paged = ( isset( $paged ) || ! ( empty( $paged ) ) ) ? $paged : 1;
//set a parent-post ID, by which to filter child posts here
$question_id = $request->get_param( 'post_parent' );
//if the parent post is not set, return null
$question_id = ( isset( $question_id ) || ! ( empty($question_id) ) ) ? $question_id : null;
// Get the child posts under a specific parent post
$posts = get_posts( array(
'paged' => $paged,
'posts_per_page' => 10,
'order' => 'asc',
'post_parent' => $question_id,
'post_type' => 'answer',
)
);
// Loop through the posts and push the desired data to the array we've initialized earlier in the form of an object
foreach( $posts as $post ) {
$id = $post->ID;
$post_author = get_user_by( 'ID', $post->post_author );
// Get author name, and add it to response directly
$author_display_name = $post_author->display_name;
//get author avatar and add it directly. You need to install a plugin called "Simple Local Avatars" for this to work here => https://wordpress/plugins/simple-local-avatars/
$avatar = get_simple_local_avatar($post_author->ID, 150);
$posts_data[] = (object) array(
'id' => $id,
'slug' => $post->post_name,
'type' => $post->post_type,
'title' => $post->post_title,
'content' => $post->post_content,
'question' => $post->post_parent,
'avatar_url' => $avatar,
'author_name' => $author_display_name,
'post_date' => $post->post_date,
);
}
return $posts_data;
}
Now you can querry your child posts (custom post type say answer) based on parent post ID under which they were posted (another custom post type say question). If the Question id is 123, and domain is https://domain, then this is your URL from the endpoint above: https://domain/wp-json/wp/v2/answers/question=123?page=1