admin管理员组

文章数量:1429938

I'm building my own WordPress theme, and I would like for my search queries to search posts by keywords in the title, categories, tags, and content. As of now, I believe that my theme is only searching by keywords in the title and content.

How do I determine which fields are currently being searched? Once I determine that, how do I modify my search query so that it searches posts by the fields listed above?

I've tried something similar to the tutorial below. If seeing code from my theme would help you answer, let me know what files you would need and I'll post them.

<?php
/**
 * Extend WordPress search to include custom fields
 *
 * 
 */

/**
 * Join posts and postmeta tables
 *
 * 
 */
function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }

    return $join;
}
add_filter('posts_join', 'cf_search_join' );

/**
 * Modify the search query with posts_where
 *
 * 
 */
function cf_search_where( $where ) {
    global $pagenow, $wpdb;

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

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

/**
 * Prevent duplicates
 *
 * 
 */
function cf_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );

I'm building my own WordPress theme, and I would like for my search queries to search posts by keywords in the title, categories, tags, and content. As of now, I believe that my theme is only searching by keywords in the title and content.

How do I determine which fields are currently being searched? Once I determine that, how do I modify my search query so that it searches posts by the fields listed above?

I've tried something similar to the tutorial below. If seeing code from my theme would help you answer, let me know what files you would need and I'll post them.

<?php
/**
 * Extend WordPress search to include custom fields
 *
 * https://adambalee
 */

/**
 * Join posts and postmeta tables
 *
 * http://codex.wordpress/Plugin_API/Filter_Reference/posts_join
 */
function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }

    return $join;
}
add_filter('posts_join', 'cf_search_join' );

/**
 * Modify the search query with posts_where
 *
 * http://codex.wordpress/Plugin_API/Filter_Reference/posts_where
 */
function cf_search_where( $where ) {
    global $pagenow, $wpdb;

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

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

/**
 * Prevent duplicates
 *
 * http://codex.wordpress/Plugin_API/Filter_Reference/posts_distinct
 */
function cf_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );
Share Improve this question edited Apr 23, 2019 at 23:05 Nicolai Grossherr 18.9k8 gold badges64 silver badges109 bronze badges asked Apr 23, 2019 at 17:00 tpsReportstpsReports 417 bronze badges 1
  • Themes have no business modifying core search behaviour. Themes are for presentation only. Any such functionality belongs in a plugin. – Jacob Peattie Commented Apr 24, 2019 at 2:12
Add a comment  | 

1 Answer 1

Reset to default 1

I found a solution that allows me to search posts by tags and categories while still searching title and content. This does exactly what I was looking for.

Credit: https://rfmeier/include-category-and-post-tag-names-in-the-wordpress-search/

add_filter( 'posts_join', 'search_join', 10, 2 );
/**
 * Joins the terms, term_relationship, and term_taxonomy tables.
 *
 * @global $wpdb
 *
 * @param string $join The sql JOIN clause.
 * @param object $query The current WP_Query instance.
 *
 * @return string $join
 */
function search_join( $join, $query ) {

    global $wpdb;

    if ( is_main_query() && is_search() ) {

        $join .= "
        LEFT JOIN
        (
            {$wpdb->term_relationships}
            INNER JOIN
                {$wpdb->term_taxonomy} ON {$wpdb->term_taxonomy}.term_taxonomy_id = {$wpdb->term_relationships}.term_taxonomy_id
            INNER JOIN
                {$wpdb->terms} ON {$wpdb->terms}.term_id = {$wpdb->term_taxonomy}.term_id
        )
        ON {$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id ";

    }

    return $join;

}

add_filter( 'posts_where', 'custom_posts_where', 10, 2 );
/**
 * Callback for WordPress 'posts_where' filter.
 *
 * Modify the where clause to include searches against a WordPress taxonomy.
 *
 * @global $wpdb
 *
 * @param string $where The where clause.
 * @param WP_Query $query The current WP_Query.
 *
 * @return string The where clause.
 */
function custom_posts_where( $where, $query ) {

    global $wpdb;

    if ( is_main_query() && is_search() ) {

        // get additional where clause for the user
        $user_where = custom_get_user_posts_where();

        $where .= " OR (
                        {$wpdb->term_taxonomy}.taxonomy IN( 'category', 'post_tag' )
                        AND
                        {$wpdb->terms}.name LIKE '%" . esc_sql( get_query_var( 's' ) ) . "%'
                        {$user_where}
                    )";

    }

    return $where;

}

function custom_get_user_posts_where() {

  global $wpdb;

  $user_id = get_current_user_id();
  $sql     = '';
  $status  = array( "'publish'" );

  if ( $user_id ) {

      $status[] = "'private'";

      $sql .= " AND {$wpdb->posts}.post_author = {$user_id}";

  }

  $sql .= " AND {$wpdb->posts}.post_status IN( " . implode( ',', $status ) . " ) ";

  return $sql;

}

add_filter( 'posts_groupby', 'custom_posts_groupby', 10, 2 );
/**
 * Callback for WordPress 'posts_groupby' filter.
 *
 * Set the GROUP BY clause to post IDs.
 *
 * @global $wpdb 
 *
 * @param string $groupby The GROUPBY caluse.
 * @param WP_Query $query The current WP_Query object.
 *
 * @return string The GROUPBY clause.
 */
function custom_posts_groupby( $groupby, $query ) {

  global $wpdb;

  if ( is_main_query() && is_search() ) {
      $groupby = "{$wpdb->posts}.ID";
  }

  return $groupby;

}

本文标签: wp queryHow do I search WordPress by different fields without a plugin