Thank you very much! I've tested it and it seems to work perfectly. The no-clip feature is really nice.
Have you submitted it to Trac as an enhancement?
Best regards,
Juan
This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.
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.
Thank you very much! I've tested it and it seems to work perfectly. The no-clip feature is really nice.
Have you submitted it to Trac as an enhancement?
Best regards,
Juan
Hey Juanitou,
nice to hear from you.
I noticed, that I still had some improvements to do. The problem was to get well-formed XML out of this function, because it will only return plain text. Since some special charakters like the ampersand (&) are forbidden in XML, the xml rendering of the result page will fail, if one of those chracters is part of the returned MyContextSummary.
So I did another update, that handles this problem and converts all special characters to htmlentities at the end of the function.
// New Result-function with highlighted search-strings
// refer to: http://www.silverstripe.org/form-questions/show/262339?start=0
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 the search string to be in the middle of our block to give it some context
$position = max(0, $position - ($characters / 2));
// We don't want to start mid-word
if($position > 0)
{
$position = max((int) strrpos(substr($text, 0, $position), ' '), (int) strrpos(substr($text, 0, $position), "\n"));
}
$summary = substr($text, $position, $characters);
// We also don't want to end mid-word
$offset = $characters+$position;
if ($offset > strlen($text)-1) $offset = strlen($text)-1;
$position = min((int) strpos($text, ' ', $offset), (int) strpos($text, "\n", $offset));
if ($position) $summary = $summary.substr($text, $offset, $position-$offset);
if($highlight)
{
// Setting the content that will be inserted before and after the highlighted words
$before_content = "<span class=\"highlight\">";
$after_content = "</span>";
// We have to insert content without any html-entities in the first place
// The following two lines should not be altered
$before_placeholder = "%BEFORE_CONTENT%";
$after_placeholder = "%AFTER_CONTENT%";
// Save the different search values into an array
$stringPieces = explode(' ', $string);
foreach($stringPieces as $stringPiece)
{
//Setting the start from where $stringPiece will be searched
$offset = 0;
// Recursively add before_placeholder and after_placeholder around all found $stringPiece
while($position = stripos($summary, $stringPiece, $offset))
{
$summary =
substr($summary, 0, $position)
.$before_placeholder
.substr($summary, $position, strlen($stringPiece))
.$after_placeholder
.substr($summary, $position + strlen($stringPiece), strlen($summary)-($position+1));
$offset = $position + strlen($before_placeholder) + strlen($after_placeholder);
}
}
}
// Re-add all htmlentities in order to get well-formed XML
$summary = htmlentities($summary, ENT_COMPAT , 'UTF-8');
if ($highlight)
{
// Replacing the placeholders with the set content
$summary = str_replace($before_placeholder , $before_content , $summary);
$summary = str_replace($after_placeholder , $after_content , $summary);
}
return trim($summary);
}
Bravo! You should submit it to Trac. Thanks again.
hmm, did doesnt work for me :-(
When I use this:
<% control Results %>
<a class="searchResultHeader" href="$Link">
<% if MenuTitle %>
<h3>$MenuTitle</h3>
<% else %>
<h3>$Title</h3>
<% end_if %>
</a>
<p><% if Content %> … $MyContextSummary(375); …<% end_if %></p>
<a class="read-more" href="$Link" title="<% _t('Globals.READ_MORE_ON') %> "{$Title}""><% _t('Globals.READ_MORE_ON') %> "{$Title}"</a>
<% if last %><% else %><div class="seperator"></div><% end_if %>
<% end_control %>
Hi! What do you mean? What’s the error? Did you put this code in Page_results.ss? Apart from a semi-colon after $MyContextSummary(375); that should not be there, I can’t see where the problem can be.
Get no erros, but nothing is showing :(
I've added the function the my Page.php
And that code to my page_results.ss
like this solution, works for me
@Stijn: you might have made the same mistake as me initially: don't add the MyContextSummary function to the controller (Page_Controller) class but to the model (Page) class.
That's a piece of art Ultimate!
Exactly what I was (poorly) trying to do.
Thanks.
But I still seem to have the problem you originally had where the case (uppercase or lowecase etc.) of the word found in the text is replaced by the case of the query word.
I think I understand that you extract the word directly from the text with "substr($summary, $position, strlen($stringPiece))" but mine is still replaced by the Search String.
Some more help please?
Or anyone else?
Thanks