$conf, $runtime; function_exists('chdir') AND chdir(APP_PATH); $r = 'mysql' == $conf['cache']['type'] ? website_set('runtime', $runtime) : cache_set('runtime', $runtime); } function runtime_truncate() { global $conf; 'mysql' == $conf['cache']['type'] ? website_set('runtime', '') : cache_delete('runtime'); } register_shutdown_function('runtime_save'); ?>json - How do I filter Child Posts by Parent Post ID for Custom Post types in Wordpress REST API response?|Programmer puzzle solving
最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

json - How do I filter Child Posts by Parent Post ID for Custom Post types in Wordpress REST API response?

matteradmin10PV0评论

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 badges
Add a comment  | 

2 Answers 2

Reset to default 0

I'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

Post a comment

comment list (0)

  1. No comments so far