my current search only shows POSTS as results.


My site has categories for George Clooney, George R.R. Martin etc. How do I get a list of categories that match the search term to show at the top of the results page?

I have tried this:

$search_query = get_search_query();

$term = get_term_by( 'name', $search_query, 'category' );
if ( !empty( $terms ) && !is_wp_error( $terms ) ){
    echo "<ul>";
    foreach ( $terms as $term ) {
    echo "<li>" . $term->name . "</li>"; 
    echo "</ul>";

But I don't get any output

  • Do you want to show only categories or categories and posts?
    – gmazzap
    Commented Aug 24, 2014 at 4:05
  • I want to show matching categories first, then matching posts below. I already have the matching posts code. Commented Aug 24, 2014 at 16:46

2 Answers 2


Essentially what you need is show the categories the current queried posts belong. I'll post here a function that take as argument a taaxonomy (or an array of taxonomies) and return all the terms in that (those) taxonomy(ies) that are assigned to all queried posts.

function queried_posts_terms( $taxonomies = 'category' ) {
  global $wp_query, $wpdb;
  if ( empty( $wp_query->posts ) ) return FALSE;
  $ids = wp_list_pluck( $wp_query->posts, 'ID' );
  $taxonomies = array_filter( (array) $taxonomies, function( $tax ) {
    if ( is_string( $tax ) ) {
      $tax = sanitize_title( $tax );
      return taxonomy_exists( $tax ) ? esc_sql( $tax ) : NULL;
  } );
  if ( empty( $taxonomies ) ) return FALSE;
  $sql = "SELECT t.name, t.slug, t.term_group, tt.*
    FROM {$wpdb->terms} t
    INNER JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id
    INNER JOIN {$wpdb->term_relationships} tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
    WHERE tr.object_id IN (" . implode( ', ', $ids ) . ")
    AND tt.taxonomy IN ('" . implode( "', '", $taxonomies ) . "')
    GROUP BY t.term_id";
  return $wpdb->get_results( $sql );

Once you have this function in your functions.php (or in an active plugin) in your template, propably search.php just use:

if ( is_search() ) {
  $cats = queried_posts_terms( 'category' );
  echo ! empty( $cats ) ? '<ul>' : '';
  foreach( $cats as $cat ) {
    printf( '<li><a href="%s">%s</a></li>', get_term_link($cat), esc_html($cat->name) );
  echo ! empty( $cats ) ? '</ul>' : '';
  • I did it but I guess it's finding every post with the search term in it. I just want to find the categories that match the search term: Search term "george" Results: Price George, George Clooney George Michael etc newslines.org/?s=george Commented Aug 25, 2014 at 3:16
  • 1
    @MarkDevlin Ok, I misunderstand the question. I think that you should use another query parameter instead of s, because that in WordPress is reserved to search posts, not category terms. It means that if you force it to search terms instead of posts you'll not be able anymore to use that feature for other post types. Moreover it will probably break something somewhere, as usually happen when you force a core feature to do something completely different from what it was designed for.
    – gmazzap
    Commented Aug 25, 2014 at 6:00

You can edit your search.php file to essentially run multiple search loops, like this...

    global $query_string;

    $query_args = explode("&", $query_string);
    $search_query = array();

    foreach($query_args as $key => $string) {
        $query_split = explode("=", $string);
        $search_query[$query_split[0]] = urldecode($query_split[1]);
    } // foreach

    $first_args = $search_query;

    // set up your additional query parameters
    // I just used a sample of only getting a certain category, but you get the idea

    $first_args['cat'] = 162;
    $first_args['orderby'] = 'date';

    $first_search = new WP_Query($first_args);

    // Do your loop output stuff here


Basically what you're doing is grabbing the query string (search string), and running a custom WP_Query using your additional parameters. After you run the first custom query to get matching categories, you can just run an additional query using the original $query_string.

I know that doesn't do EXACTLY what you want but it should give you the starting point to make it happen. I'm happy to help if you have any further questions.

  • How would I do that to search through all categories instead of one? Commented Aug 23, 2014 at 20:21
  • Just take out that generic category parameter I put in there. By default, your loop will check all categories. Check out codex.wordpress.org/Class_Reference/WP_Query for a list of all available parameters. You'll just have to enter them like I did above since you already have a parameters array built.
    – Will S.
    Commented Aug 23, 2014 at 20:26
  • I'm confused about the loop. My current loop uses <?php while (have_posts()) : the_post(); ?> should I use a different command to loop the categories? Commented Aug 24, 2014 at 4:34
  • Post your search.php code and I'll try to walk you through it
    – Will S.
    Commented Aug 24, 2014 at 16:33
  • Considering the comment above comment by G.M. will your solution work for categories? Commented Aug 25, 2014 at 16:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.