word limiter closing tags

Derek Jones edited this page Jul 5, 2012 · 8 revisions
Clone this wiki locally

Category:Helper::Community | Category:Helper::Text

Suppose you want to make a page that shows the first 500 words of your text, and your text contains tags that change the layout (e.g. , ,...). If the word_limiter function cuts off your text before the closing tags, the rest of your page will be affected, e.g. by being printed bold.

So an auto-tag-closing word_limiter() function would be helpful. Here's how to do it. In the text_helper file, enter this function:

function closeTags($string)
{
    // coded by Constantin Gross <connum at googlemail dot com> / 3rd of June, 2006
    // (Tiny little change by Sarre a.k.a. Thijsvdv)
    $donotclose=array('br','img','input'); //Tags that are not to be closed
    
    //prepare vars and arrays
    $tagstoclose='';
    $tags=array();
    
    //put all opened tags into an array  /<(([A-Z]|[a-z]).*)(( )|(>))/isU
    preg_match_all("/<(([A-Z]|[a-z]).*)(( )|(>))/isU",$string,$result);
    $openedtags=$result[1];
    // Next line escaped by Sarre, otherwise the order will be wrong
    // $openedtags=array_reverse($openedtags);
    
    //put all closed tags into an array
    preg_match_all("/<\/(([A-Z]|[a-z]).*)(( )|(>))/isU",$string,$result2);
    $closedtags=$result2[1];
    
    //look up which tags still have to be closed and put them in an array
    for ($i=0;$i<count($openedtags);$i++) {
       if (in_array($openedtags[$i],$closedtags)) { unset($closedtags[array_search($openedtags[$i],$closedtags)]); }
           else array_push($tags, $openedtags[$i]);
    }
    
    $tags=array_reverse($tags); //now this reversion is done again for a better order of close-tags
    
    //prepare the close-tags for output
    for($x=0;$x<count($tags);$x++) {
    $add=strtolower(trim($tags[$x]));
    if(!in_array($add,$donotclose)) $tagstoclose.='</'.$add.'>';
}

//and finally
return $string . $tagstoclose;
}

Then change the word_limiter() function to this:

function word_limiter($str, $n = 100, $end_char = '')
{
    if (strlen($str) < $n)
    {
        return closeTags($str);
    }
    
    $words = explode(' ', preg_replace("/\s+/", ' ', preg_replace("/(\r\n|\r|\n)/", " ", $str)));
    
    if (count($words) <= $n)
    {
        return closeTags($str);
    }
            
    $str = '';
    for ($i = 0; $i < $n; $i++)
    {
        $str .= $words[$i].' ';
    }
    
    $str = closeTags($str);
    return trim($str).$end_char;
}

```And that closes the tags in the correct order! :)