Hack: Show Keywords In Search Results

I’ve seen hacks posted elsewhere that highlight the keywords on the WordPress search page. This is handy because the user can see where the keywords show up in the title of each result. But I have two problems with most of the hacks I have seen.

First, most of them only do this for the title. I’d like it to be in the excerpt for the post as well. Second, most of them have you editing the theme. I’d rather do this as filters that you can add to your own plugin or the functions.php file.

So here is my solution. It uses a filter for the_title. It checks to see if these are search results being displayed, and only alters the text in that case. It then uses stripos to look for the keyword, so not worrying about case. Then I’m using a trio of substr functions to get the text before, during and after the match. This avoids confusing regex syntax, and it also allows for the bolded keyword to appear in the text just as it was before, not as it is in the search. So when the user searches for “castle” and “Castle” is found, the C is uppercase.

function wpfilter_search_results_text($text) {
	$q = get_search_query();
	if (is_search()) {
		$pos = stripos($text,$q);
		if ($pos !== FALSE) {
			return substr($text,0,$pos) . '<strong>' . substr($text,$pos,strlen($q)) . '</strong>' . substr($text,$pos+strlen($q));
	return $text;

But this only works for the title. To get it to work for the excerpt, we can use the exact same function. That is why I named it wpfilter_search_results_text and not _title.


Now this is a good starting point. One problem is that it assumes a single keyword or phrase. So while the search term¬†norman castle shows results, the words norman and castle are not bolded, only¬†norman castle as consecutive words. It also doesn’t handle multiple occurrences of the words in text.

You can take care of that with some loops and/or clever regex functions. But I’ll leave it relatively simple for now.

Leave a Reply

Your email address will not be published. Required fields are marked *