Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Form Questions /

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Highlight search query in results page?


Go to End


25 Posts   12937 Views

Avatar
SilverRay

Community Member, 167 Posts

13 June 2009 at 4:54pm

Hi,

OK, I have the usual search form (as per Ingo's book ;) ), like so:

	function results($data, $form) {
		$results = $form->getResults(null, $data);		
		$searchQueryTitle = $form->getSearchQuery($data);

		$templateData = array(
			'Results' => $results,
			'SearchQueryTitle' => $searchQueryTitle,
			'Title' => 'Search Results'
		);
		return $this->customise($templateData)->renderWith(
			array('Page_results', 'Page')
		);
	}

Now, I would like to highlight the search term in the results by inserting some css class with a function like str_ireplace or similar. Anybody having experience with this, or can give some hints on how to proceed?

Thanks!

Avatar
SilverRay

Community Member, 167 Posts

15 June 2009 at 10:17pm

OK, I got a little bit further, but not quite. I added the following:

	function results($data, $form) {
		$results = $form->getResults(null, $data);		
		$searchQueryTitle = $form->getSearchQuery($data);

		$newSet = new DataObjectSet();
		foreach($results as $result) {
			$result = str_ireplace("$searchQueryTitle", "<span class=\"highlight\">$searchQueryTitle</span>", $result->Content);
			$newSet->push($result);
		}
				
		$templateData = array(
			'Results' => $newSet,
			'SearchQueryTitle' => $searchQueryTitle,
			'Title' => 'Search Results'
		);
		return $this->customise($templateData)->renderWith(
			array('Page_results', 'Page')
		);
	}

This gives me a blank page. When I change 'Results' => $newSet to 'Results' => $results again, of course it works in the old way (without highlighting). What is the magic that I'm missing? Thanks!

Avatar
SilverRay

Community Member, 167 Posts

16 June 2009 at 11:07pm

Nobody? Please? ;)

Avatar
Juanitou

Community Member, 323 Posts

16 July 2009 at 7:48am

Edited: 16/07/2009 8:22am

Hi!

You could get some inspiration by looking at the ContextSummary function in sapphire/core/model/fieldtypes/Text.php

By the way, if you find a custom solution for this or a method overloading ContextSummary I'll be happy to know about it (since I don't know how to do it myself).

Regards,
Juan

Avatar
SilverRay

Community Member, 167 Posts

16 July 2009 at 1:17pm

Well, yeah, that file I have perused already, initially. I didn't have much time to pursue the whole thing, of course I will post code when I solve it (or perhaps someone will beat me to it ;) )

Avatar
Juanitou

Community Member, 323 Posts

22 July 2009 at 9:25pm

Edited: 22/07/2009 9:26pm

Hi!

As I'm not good at PHP, I copied ContextSummary and added some improvements (?), since I had problems with encoded chars, stripped <br /> sticking words and results coming from blog entries including BBCode.

In Page class:

function MyContextSummary($characters = 500, $string = false, $striphtml = true, $highlight = true) {
		
	if(!$string) $string = $_REQUEST['Search'];	// Use the default "Search" request variable (from SearchForm)
	
	/*** Prepare Content ***/
	// Replace <br /> in order to get separate words
	$content = str_replace('<br />', ' ', $this->Content);
	// Decoding entities prevents XML validation error
	$content = html_entity_decode($content, ENT_COMPAT , 'UTF-8');
	// Remove HTML tags so we don't have to deal with matching tags
	$text = strip_tags($content);
	// Remove BBCode
	$pattern = '|[[\/\!]*?[^\[\]]*?]|si';
	$replace = '';
	$text = preg_replace($pattern, $replace, $text);
	
	// Find the search string
	$position = (int) stripos($text, $string);
	
	// We want to search string to be in the middle of our block to give it some context
	$position = max(0, $position - ($characters / 2));

	if($position > 0) {
		// We don't want to start mid-word
		$position = max((int) strrpos(substr($text, 0, $position), ' '), (int) strrpos(substr($text, 0, $position), "\n"));
	}
	
	$summary = substr($text, $position, $characters);
	$stringPieces = explode(' ', $string);
		if($highlight) {
		// Add a span around all key words from the search term as well
		if($stringPieces) foreach($stringPieces as $stringPiece) {
			$summary = str_ireplace($stringPiece, "<span class=\"highlight\">$stringPiece</span>", $summary);
		}
	}

	return trim($summary);
}	

In Page_results.ss:

…
<% if Content %>
	<p>&hellip;$MyContextSummary(375)&hellip;</p>
<% else %>
…

For what is worth,
Juan

Avatar
SilverRay

Community Member, 167 Posts

23 July 2009 at 5:11pm

OK, so that works for you? When I find the time, I will look into it as well (using your example).

Avatar
Juanitou

Community Member, 323 Posts

23 July 2009 at 8:06pm

If it didn't worked I wouldn't have posted it…

Go to Top