ZOO Teaser Text
When creating a Joomla website that uses ZOO for content management, we usually come across having to set up teaser items that act as a feed from a certain application or category. Using the same text element for entering a full length article and for a "preview" on the teaser item can give us very long blocks of text that can clutter the page.
To fix this, we use a little trick that tells ZOO to cut off the text after a certain number of characters. We can also use this to strip the text of all formatting - or to allow a number of specific tags.
Below is the code we need to implement into the current php.
The first code needs to be put inside the first class in this php file: administrator/components/com_zoo/helpers/renderer.php
public static function truncatewtags($text, $length, $suffix = '…', $isHTML = true){
$i = 0;
$simpleTags=array('br'=>true,'hr'=>true,'input'=>true,'image'=>true,'link'=>true,'meta'=>true);
$tags = array();
if($isHTML){
preg_match_all('/<[^>]+>([^<]*)/', $text, $m, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
foreach($m as $o){
if($o[0][1] - $i >= $length)
break;
$t = substr(strtok($o[0][0], " \t\n\r\0\x0B>"), 1);
// test if the tag is unpaired, then we mustn't save them
if($t[0] != '/' && (!isset($simpleTags[$t])))
$tags[] = $t;
elseif(end($tags) == substr($t, 1))
array_pop($tags);
$i += $o[1][1] - $o[0][1];
}
}
// output without closing tags
$output = substr($text, 0, $length = min(strlen($text), $length + $i));
// closing tags
$output2 = (count($tags = array_reverse($tags)) ? '</' . implode('></', $tags) . '>' : '');
// Find last space or HTML tag (solving problem with last space in HTML tag eg. <span class="new">)
$pos = (int)end(end(preg_split('/<.*>| /', $output, -1, PREG_SPLIT_OFFSET_CAPTURE)));
// Append closing tags to output
$output.=$output2;
// Get everything until last space
$one = substr($output, 0, $pos);
// Get the rest
$two = substr($output, $pos, (strlen($output) - $pos));
// Extract all tags from the last bit
preg_match_all('/<(.*?)>/s', $two, $tags);
// Add suffix if needed
if (strlen($text) > $length) { $one .= $suffix; }
// Re-attach tags
$output = $one . implode($tags[0]);
//added to remove unnecessary closure
$output = str_replace('</!-->','',$output);
return $output;
}
}
This sets up the function we're going to use called truncatewtags
.
This is what we need to call on in our content renderer files to get it to run the function and cut our text.
The second code here is what we need to copy into any of the renderer files where we want this function to occur. In this article we'll be putting into the content position of our teaser file but it can be used in any other places that use content from ZOO.
We'll place this code here and replace our content position: /media/zoo/applications/[yourapplication]/templates/[yourtemplate]/renderer/item/teaser.php
$teaserText = $this->renderPosition('content', array('style' => 'block'));
$teaserText= $this->app->renderer->truncatewtags($teaserText, 300, '...', true);
echo $teaserText;
The way this is set up is it says truncatewtags
is being executed on $teaserText
(which is $this
- whichever position you've replaced it with, in this case 'content'), amount of characters before being cut off (in this case, 300), the suffix that will be displayed after the last character (in this case '...') and lastly - 'true' tells the variable to execute $isHTML
, which can be seen in the first excerpt of code.
To change the number of characters allowed, simply change the number (above it is 300). To allow certain tags in your teaser text, we must first strip all tags from the content. We do this by adding a strip_tags
fuction.
$teaserText = $this->renderPosition('content', array('style' => 'block'));
$teaserText = strip_tags($teaserText); //Remove all tags
$teaserText= $this->app->renderer->truncatewtags($teaserText, 300, '...', true);
echo $teaserText;
To add exceptions for specific tags, we add them like this after the variable we're stripping them from:
$teaserText = $this->renderPosition('content', array('style' => 'block'));
$teaserText = strip_tags($teaserText, '<p><h2><h3><h4><h5><h6>'); //Remove all tags, except listed
$teaserText= $this->app->renderer->truncatewtags($teaserText, 300, '...', true);
echo $teaserText;
Although this is a great way to do this, if you update ZOO, it will overwrite the files and you'll lose the code. We have come up with another way to implement this so that you'll never have to replace it. View our method here