Posts search – categories

By default, the WordPress search engine only searches the titles and content of the posts. In order to include the category of the post in the search, the two following code snippets should be added in the functions.php file in theme folder. The first of them creates a class that implements the methods responsible for searching by taxonomy. The second fragment creates a class object for the category.

taxonomy = $taxonomy;
		$this->slug = str_replace( '-', '_', $this->taxonomy );
		add_filter( 'posts_join', array( $this, 'posts_join' ) , 10, 2 );
		add_filter( 'posts_where', array( $this, 'posts_where' ), 10, 2 );
		add_filter( 'posts_groupby', array( $this, 'posts_groupby' ), 10, 2 );
	}

	public function posts_join( $join, $query ) {
		global $wpdb;
		if ( is_main_query() && is_search() ) {
			$join .= "
                LEFT JOIN
                (
                    {$wpdb->term_relationships} AS term_relationship_search_by_taxonomy_{$this->slug}
                    INNER JOIN
                        {$wpdb->term_taxonomy} AS term_taxonomy_search_by_taxonomy_{$this->slug} 
                        ON term_taxonomy_search_by_taxonomy_{$this->slug}.term_taxonomy_id = term_relationship_search_by_taxonomy_{$this->slug}.term_taxonomy_id
                    INNER JOIN
                        {$wpdb->terms} terms_search_by_taxonomy_{$this->slug} 
                        ON terms_search_by_taxonomy_{$this->slug}.term_id = term_taxonomy_search_by_taxonomy_{$this->slug}.term_id
                )
                ON {$wpdb->posts}.ID = term_relationship_search_by_taxonomy_{$this->slug}.object_id  
            ";
		}
		return $join;
	}

	public function posts_where( $where, $query ) {
		global $wpdb;
		if ( is_main_query() && is_search() ) {
			$where .= " OR (
                            term_taxonomy_search_by_taxonomy_{$this->slug}.taxonomy = '{$this->taxonomy}'
                            AND (
                                terms_search_by_taxonomy_{$this->slug}.name LIKE '%" . $wpdb->esc_like( get_query_var( 's' ) ) . "%'
                                )
                      )";
		}
		return $where;
	}

	public function posts_groupby( $groupby, $query ) {
		global $wpdb;
		if ( is_main_query() && is_search() ) {
			$groupby = "{$wpdb->posts}.ID";
		}
		return $groupby;
	}

}

View the code on Gist.

View the code on Gist.

If you do not use the child theme, remember that changes made to the functions.php file will be overwritten when the theme is updated.

While copying code to functions.php file it is not nessesary to copy <?php opening tag.

About grola

Passionate about Wordpress and WooCommerce for many years. Author of plugins and short snippets improving Wordpress and WooCommerce.

View all posts by grola →