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 Aug 24 '14 at 4:05
  • I want to show matching categories first, then matching posts below. I already have the matching posts code. – Mark Devlin Aug 24 '14 at 16:46

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 – Mark Devlin Aug 25 '14 at 3:16
  • @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 Aug 25 '14 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? – Mark Devlin Aug 23 '14 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. Aug 23 '14 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? – Mark Devlin Aug 24 '14 at 4:34
  • Post your search.php code and I'll try to walk you through it – Will S. Aug 24 '14 at 16:33
  • Considering the comment above comment by G.M. will your solution work for categories? – Mark Devlin Aug 25 '14 at 16:48

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.