Search WP API using the post title

I'm using the WP REST API v2 to try and search for all posts with the same title, what I'm trying to do is create a sort of head-to-head/previous meetings page for 2 teams.

At the moment i can retrieve a single post with a slug no problem

.../wp-json/sportspress/v2/events?slug=team1-vs-team2

When i use a search it retrieves all the events with team1 and team2, but also all references to team1 2 from post content which is not what I want...

.../wp-json/sportspress/v2/events?search=team1+team2

How do i retrieve a post using the search using the exact post title as shown below in title > rendered ??

0   
  id    60455
  date  "2016-11-22T19:30:00"
  date_gmt  "2016-11-22T19:30:00"
  modified  "2016-11-23T09:25:29"
  modified_gmt  "2016-11-23T07:25:29"
  slug  "team1-vs-team2"
  status    "publish"
  type  "sp_event"
  link  ".../event/team1-vs-team2/"
  title 
      rendered  "Team1 vs Team2"

Topic rest-api Wordpress

Category Web


function my_website_datas(){
    wp_enqueue_style(YOUR CSS link -- you must know this)
    wp_enqueue_script('my-theme-js', get_theme_file_uri('/js/scripts-bundled.js'), NULL, 'v1' , TRUE  );
    wp_localize_script('my-theme-js', 'websiteData', array(
       'root_url'  => get_site_url(),
        'nonce' =>  wp_create_nonce('wp_rest')   
    
       ))
     }
       add_action('wp_enqueue_scripts','my_website_datas');

create new API route

     add_action('rest_api_init', 'my_new_search_api');
     function my_new_search_api(){

       //3 args - the 1st and 2nd is the API route you will hook
       // like search_route/v1/search?term=  in your getJson
       register_rest_route('search_route/v1','search', array(
        'methods'       => WP_REST_SERVER::READABLE,
        'callback'      => 'customSearchResults'  // this is your below function

      ));
     }

Create the callback function

      function customSearchResults( $data ) {

        /* Create you  new Query */
            $mainQuery = new WP_Query( array(
                'post_type'     => array('post','page','post_type1'),
                's'             => sanitize_text_field( $data['term'])  // v1/search?term 
            ));

        // create your array to append if the user attempt to search for kind of taxonomy
        $results = array( 
                'generalInfo'       => array(),
                'post_type1'        => array()
            );

        while($mainQuery->have_posts()){
            $mainQuery->the_post();

        //here when the taxonomy matches it will append the data the in array above
            if( get_post_type() == 'posts' OR get_post_type() == 'page'){
                    array_push($results['generalInfo'], array(
                        'title'         => get_the_title(),
                        'permalink'     => get_the_permalink(),
                        'postType'      => get_post_type(),
                        'authorName'    => get_the_author()
                    ));
        
            } 
        
            if( get_post_type() == 'post_type1'){
        
                    array_push($results['post_type1'], array(
                        'title'     => get_the_title(),
                        'permalink' => get_the_permalink(),
                        'postType'  => get_post_type(),
                        'authorName'    => get_the_author()
                    ));
        
                } 
    
      return $results;
    }
}

   
    

Next in your JS file The code is too long you must guess this this.searchField.val() part haha

 $.getJSON(websiteData.root_url + '/wp-json/university/v1/search?term=' + 
   this.searchField.val(), (results) => {
   
  // now you can append the result to wherever element you want.      
   this.resultsDiv.html(`
     <p> ${results} </p> `)

   }
    

This code will work if you know what you are doing. Hope this helps!


You cannot do this through wp json, please copy the following code in the functions.php:

function __search_by_title_only( $search, &$wp_query ) {
    global $wpdb;

    if ( empty( $search ) )
        return $search; // skip processing - no search term in query

    $q = $wp_query->query_vars;    
    $n = ! empty( $q['exact'] ) ? '' : '%';

    $search =
    $searchand = '';

    foreach ( (array) $q['search_terms'] as $term ) {
        $term = esc_sql( like_escape( $term ) );
        $search .= "{$searchand}($wpdb->posts.post_title LIKE '{$n}{$term}{$n}')";
        $searchand = ' AND ';
    }

    if ( ! empty( $search ) ) {
        $search = " AND ({$search}) ";
        if ( ! is_user_logged_in() )
            $search .= " AND ($wpdb->posts.post_password = '') ";
    }

    return $search;
}
add_filter( 'posts_search', '__search_by_title_only', 500, 2 );

Of course it's possible! You'll just need to add in a custom endpoint for the REST API.

To do that, drop the code below into your functions.php (or better yet, a plugin so it's not tied to your theme).

First, register the custom route and allow it to take a "title" parameter.

/**
 * Register the custom route
 *
 */
function custom_register_your_post_route() {
    register_rest_route( 'custom-search/v1', '/posts/(?P<title>.+)', array(
        array(
            'methods'  => WP_REST_Server::READABLE,
            'callback' => 'custom_get_post_sample'
        )
    ) );
} 
add_action( 'rest_api_init', 'custom_register_your_post_route' );

Next, add in the custom callback function to find and return the posts you're looking for, using the built-in WP_REST_Posts_Controller.

/**
 * Grab all posts with a specific title
 *
 * @param WP_REST_Request $request Current request
 */
function custom_get_post_sample( $request ) {
    global $wpdb;

    // params
    $post_title = $request->get_param( 'title' );
    $post_type = 'post';

    // get all of the post ids with a title that matches our parameter
    $id_results = $wpdb->get_results( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type= %s", urldecode( $post_title ), $post_type ) );
    if ( empty( $id_results ) ) {
        return rest_ensure_response( $request );
    }
    
    // format the ids into an array
    $post_ids = [];
    foreach( $id_results as $id ) {
        $post_ids[] = $id->ID;
    }

    // grab all of the post objects
    $args = array(
        'post_type' => $post_type,
        'post_status' => 'publish',
        'posts_per_page' => -1,
        'post__in' => $post_ids
    );
    $posts = get_posts( $args );
 
    // prepare the API response
    $data = array(); 
    $rest_posts_controller = new WP_REST_Posts_Controller( $post_type );
    foreach ( $posts as $post ) {       
        $response = $rest_posts_controller->prepare_item_for_response( $post, $request );
        $data[] = $rest_posts_controller->prepare_response_for_collection( $response );
    }
 
    // Return all of our post response data
    return rest_ensure_response( $data );
}

This will give you a response that looks just like the built-in Posts endpoint, including any additional data added by plugins (Yoast SEO for example).

There's plenty of additional documentation under the Extending the REST API section at wordpress.org if you need more functionality.

Hope this helps!


Unfortunately, it is not possible, but you can use slug instead.

Like this:

http://example.com/wp-json/wp/v2/posts?slug=table

Reference document URL are: https://developer.wordpress.org/rest-api/reference/pages/#arguments

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.