19

How can I get the search terms highlighted without plugin?

4 Answers 4

17

Add these 2 functions to your functions.php

function search_excerpt_highlight() {
    $excerpt = get_the_excerpt();
    $keys = implode('|', explode(' ', get_search_query()));
    $excerpt = preg_replace('/(' . $keys .')/iu', '<strong class="search-highlight">\0</strong>', $excerpt);

    echo '<p>' . $excerpt . '</p>';
}

function search_title_highlight() {
    $title = get_the_title();
    $keys = implode('|', explode(' ', get_search_query()));
    $title = preg_replace('/(' . $keys .')/iu', '<strong class="search-highlight">\0</strong>', $title);

    echo $title;
}

Edit:

To use the_content for your search results use the function below:

function search_content_highlight() {
        $content = get_the_content();
        $keys = implode('|', explode(' ', get_search_query()));
        $content = preg_replace('/(' . $keys .')/iu', '<strong class="search-highlight">\0</strong>', $content);

        echo '<p>' . $content . '</p>';
    }

In your loop or search.php file call <?php search_title_highlight(); ?> instead of <?php the_title(); ?> and use <?php search_excerpt_highlight(); ?> instead of <?php the_excerpt(); ?>

In your css add the search-highlight class which will highlight all searched words in yellow.

.search-highlight {
    background:#FFFF00  
    }
5
  • 5
    Apply preg_quote() to $keys to prevent your regex from blowing up in case of special characters like parentheses or brackets.
    – Geert
    May 1, 2011 at 7:09
  • 1
    What about highlighting the search term after the user clicks on the single and goes inside the post? Then the get_search_query() returns an empty string May 22, 2011 at 23:47
  • 1
    Those should be filters for the_excerpt and the_content instead. Anyway: Nice answer, but the comment from @Geert could be worked in :)
    – kaiser
    Oct 13, 2012 at 0:25
  • 1
    It apply <strong class="search-highlight"> code in our readmore link also if it have search term, How can we solve that.
    – user22614
    Oct 18, 2012 at 7:20
  • 1
    it is replacing the text in the readmore href also? how to fix this?
    – Naveen
    Jan 13, 2014 at 12:58
5

The above works well I've run the similar code, but tie the title and excerpt together. But found it breaks when someone enters a space " " either at the beginning or end of a search query term.

So Ive add this line:

$keys = array_filter($keys);

// Add Bold to searched term
function highlight_results($text){
     if(is_search() && !is_admin()){
     $sr = get_query_var('s');
     $keys = explode(" ",$sr);
     $keys = array_filter($keys);
     $text = preg_replace('/('.implode('|', $keys) .')/iu', ''.$sr.'', $text);
     }
     return $text;
}
add_filter('the_excerpt', 'highlight_results');
add_filter('the_title', 'highlight_results');

Hope this proves to help others.

2

The above solutions break the page if the search term appears inside HTML tags. You should use something like:

      $regEx = '\'(?!((<.*?)|(<a.*?)))(\b'. implode('|', $keys) . '\b)(?!(([^<>]*?)>)|([^>]*?</a>))\'iu';
      $text = preg_replace($regEx, '<strong class="search-highlight">\0</strong>', $text);
1
1

Combined 2 answers to use filters :

// Add class to searched terms
function highlight_results($text) {
    if (is_search() && !is_admin()) {
        $sr = get_query_var('s');
        $keys = explode(' ', $sr);
        $keys = array_filter($keys);
        $text = preg_replace('/('.implode('|', $keys) .')/iu', '<span class="search-highlight">\0</span>', $text);
    }
    return $text;
}
add_filter('the_excerpt', 'highlight_results');
add_filter('the_title', 'highlight_results');

Then in your CSS (for example) :

.search-highlight {
    background: #ffff94;
    padding: 0 2px;
}

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