0

My question is, is there a way to configure wordpress' search to, within a custom post type, search for a custom field value.

//------------html code--------------------//
<input type="text" name="keyword" id="keyword" onkeyup="fetch()"></input>
<div id="datafetch"></div>              

------------------------------------------------
//------------------function.php--------------
add_action('wp_ajax_data_fetch' , 'data_fetch');
add_action('wp_ajax_nopriv_data_fetch','data_fetch');
function data_fetch(){

  $recipes = new WP_Query(
    array(

        'post_type' => 'project5',
        'orderby' => 'rand',
        'post_status' => 'publish',
        's'   => esc_attr( $_POST['keyword'] ),


    )
)

;

I want to search in custom field value but my code search just in custom post type title.

0

Add these filters to your functions.php file

/**
 * Join posts and postmeta tables
 *
 * @link https://developer.wordpress.org/reference/hooks/posts_join/
 */
add_filter( 'posts_join', function( string $sql, WP_Query $query ) {
    global $wpdb;
    if ( !is_admin() && $query->get( 'search_meta' ) ) {
        $sql .= ' LEFT JOIN ' . $wpdb->postmeta . ' ON ' . $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }
    return $sql;
}, 10, 2 );

/**
 * Modify the search query with posts_where
 *
 * @link https://developer.wordpress.org/reference/hooks/posts_where/
 */
add_filter( 'posts_where', function( string $sql, WP_Query $query ) {
    global $wpdb;

    if ( !is_admin() && $query->get( 'search_meta' ) ) {

        $field_query = '';

        if ( is_string( $query->get( 'search_meta' ) ) ) {
            $field_name = $query->get( 'search_meta' );
            $field_query = "AND {$wpdb->postmeta}.meta_key = '{$field_name}'";
        }

        $sql = preg_replace( '/\(\s*' . $wpdb->posts . '.post_title\s+LIKE\s*(\'[^\']+\')\s*\)/', '(' . $wpdb->posts . '.post_title LIKE $1) OR (' . $wpdb->postmeta . '.meta_value LIKE $1' . $field_query . ')', $sql );
    }

    return $sql;
}, 10, 2 );

/**
 * Prevent duplicates
 *
 * @link https://developer.wordpress.org/reference/hooks/posts_distinct/
 */
add_filter( 'posts_distinct', function( string $sql, WP_Query $query ) {

    if ( !is_admin() && $query->get( 'search_meta' ) ) {
        return 'DISTINCT';
    }

    return $sql;
}, 10, 2 );

And then you just need to add the search_meta argument in your request. To search all meta values use 'search_meta' => true...

add_action( 'wp_ajax_data_fetch', 'data_fetch' );
add_action( 'wp_ajax_nopriv_data_fetch', 'data_fetch' );
function data_fetch() {

    $recipes = new WP_Query( [
        'post_type'     => 'project5',
        'orderby'       => 'rand',
        'post_status'   => 'publish',
        's'             => esc_attr( $_POST['keyword'] ),
        'search_meta'   => true
    ] );

}

Or to search a specific field value use 'search_meta' => 'MY_FIELD_NAME'...

add_action( 'wp_ajax_data_fetch', 'data_fetch' );
add_action( 'wp_ajax_nopriv_data_fetch', 'data_fetch' );
function data_fetch() {

    $recipes = new WP_Query( [
        'post_type'     => 'project5',
        'orderby'       => 'rand',
        'post_status'   => 'publish',
        's'             => esc_attr( $_POST['keyword'] ),
        'search_meta'   => 'keyword' // Name of custom meta_key
    ] );

}

This hasn't been fully tested so please keep that in mind.


EDIT

A "less overkill" approach is to use the meta parameters in WP_Query (docs here). For example...

add_action( 'wp_ajax_data_fetch', 'data_fetch' );
add_action( 'wp_ajax_nopriv_data_fetch', 'data_fetch' );
function data_fetch() {

    $input = esc_attr( $_POST[ 'keyword' ] );

    $recipes = new WP_Query( [
        'post_type'     => 'project5',
        'orderby'       => 'rand',
        'post_status'   => 'publish',
        's'             => $input,

        'meta_key'      => 'MY_CUSTOM_FIELD_DATABSE_KEY',
        'meta_value'    => $input,
        'meta_compare'  => 'LIKE'
    ] );

}
  • but it does not work – roshanak poursaeed Nov 23 '19 at 5:33
  • @roshanakpoursaeed please see my edit, replace MY_CUSTOM_FIELD_DATABSE_KEY with the name of your custom field. If this doesn't work please give more information. – Levi Cole Nov 25 '19 at 14:30

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.