Jump to:

5540 Posts in 1738 Topics by 1224 members

Customising the CMS

SilverStripe Forums » Customising the CMS » Content Summary in valid HTML (LimitWordCount)

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

Page: 1
Go to End
Author Topic: 2815 Views
  • torleif2
    Avatar
    Community Member
    4 Posts

    Content Summary in valid HTML (LimitWordCount) Link to this post

    Here's a HTML safe LimitWordCount() function. Often I want to limit the amount of words in a content block, but retain the formatting.

    eg:
    Content = <p>this <br/>paragraph would normally get cut off</p>
    getSummaryHTML (2) returns: <p>this <br/>paragraph</p>

    This current function is to be placed in the model (it would be nice to place in controller, but it doesn't work for some reason.) It would be easy to put inside your own extended HTMLText element.

    Code (in Page.php):

       /*
       * limits words to a number, but tries to validate the code
       */
       public function getSummaryHTML ($limit = 100){
          $m = 0;
          $addEplisis = '';
          $returnstr = '';
          $returnArray = array();
          $html = array();
          $chars = preg_split('/(<[^>]*[^\/]>| )/i', $this->Content, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
          foreach ($chars as $elemnt) {
             // found start tag
             if(preg_match('/^<(p|h1|h2|h3|h4|h5|h6|q|b|i|strong|em)(.*)>$/', $elemnt)){
                preg_match('/^<(p|h1|h2|h3|h4|h5|h6|q|b|i|strong|em)(.*)>$/', $elemnt, $matches);
                array_push($html, $matches[1]);// convert <p class=""> to p
                array_push($returnArray, $elemnt);
                // found end tag
             } else if(preg_match('/^<\/(p|h1|h2|h3|h4|h5|h6|q|b|i|strong|em)(.*)>$/', $elemnt)){
                preg_match('/^<\/(p|h1|h2|h3|h4|h5|h6|q|b|i|strong|em)(.*)>$/', $elemnt, $matches);
                $testelement = array_pop ($html);
                // match (ie: <p>etc</p>)
                if($testelement==$elemnt[1]) array_pop($html);
                array_push($returnArray, $elemnt);
             } else {
                // done
                if($elemnt == ' ') continue;
                array_push($returnArray, $elemnt);
                $m++;
                if($m > $limit) {
                   $addEplisis = '&hellip;';
                   break;
                }
             }
          }
          // convert start tags to end tags
          $tmpr = '';
          foreach ($html as $elemnt) {
             $tmpr.='</'.$elemnt.'>';
          }
          return implode($returnArray, ' ') . $addEplisis . $tmpr;
       }

    This will limit Content to 100 characters, and add any broken tags on to the end. If the Content is bigger than 100 characters it adds an ellipsis on the end.

    If you find any improvements, or this is already somewhere in HTMLText, let me know.

  • Benedikt
    Avatar
    Community Member
    16 Posts

    Re: Content Summary in valid HTML (LimitWordCount) Link to this post

    There is ticket for this at: http://open.silverstripe.org/ticket/4048

    I just reopened it and also linked to your workaround.

    Thanks.

  • torleif2
    Avatar
    Community Member
    4 Posts

    Re: Content Summary in valid HTML (LimitWordCount) Link to this post

    This code will find <pre> elements. I noted a bug while trying to integrate summarized text with GeSHi (the Generic Syntax Highlighter)

    public function getSummaryHTML ($limit = 150){
    $m = 0;
    $addEplisis = '';
    $returnstr = '';
    $returnArray = array();
    $html = array();
    $chars = preg_split('/(<[^>]*[^\/]>| )/i', $this->Content, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
    foreach ($chars as $elemnt) {
    // found start tag
    if(preg_match('/^<(h1|h2|h3|h4|h5|h6|q|b|i|strong|em|pre|p)(.*)>$/', $elemnt)){
    preg_match('/^<(h1|h2|h3|h4|h5|h6|q|b|i|strong|em|pre|p)(.*)>$/', $elemnt, $matches);
    array_push($html, $matches[1]);// convert <p class=""> to p
    array_push($returnArray, $elemnt);
    // found end tag
    } else if(preg_match('/^<\/(h1|h2|h3|h4|h5|h6|q|b|i|strong|em|pre|p)(.*)>$/', $elemnt)){
    preg_match('/^<\/(h1|h2|h3|h4|h5|h6|q|b|i|strong|em|pre|p)(.*)>$/', $elemnt, $matches);
    $testelement = array_pop ($html);
    // match (ie: <p>etc</p>)
    if($testelement==$elemnt[1]) array_pop($html);
    array_push($returnArray, $elemnt);
    } else {
    // done
    if($elemnt == ' ') continue;
    array_push($returnArray, $elemnt);
    $m++;
    if($m > $limit) {
    $addEplisis = '&hellip; <small><i>(text truncated)</i></small>';
    break;
    }
    }
    }
    // convert start tags to end tags
    $tmpr = '';
    foreach ($html as $elemnt) {
    $tmpr.='</'.$elemnt.'>';
    }
    $v = new HTMLText();
    $v->value = implode($returnArray, ' ') . implode($html, '') . $addEplisis . $tmpr;
    return $v;
    }

    2815 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.