56

I have text stored in the php variable $text. This text can be 100 or 1000 or 10000 words. As currently implemented, my page extends based on the text, but if the text is too long the page looks ugly.

I want to get the length of the text and limit the number of characters to maybe 500, and if the text exceeds this limit I want to provide a link saying, "Read more." If the "Read More" link is clicked, it will show a pop with all the text in $text.

josliber
  • 43,891
  • 12
  • 98
  • 133
Scorpion King
  • 1,878
  • 8
  • 38
  • 45

13 Answers13

162

This is what I use:

// strip tags to avoid breaking any html
$string = strip_tags($string);
if (strlen($string) > 500) {

    // truncate string
    $stringCut = substr($string, 0, 500);
    $endPoint = strrpos($stringCut, ' ');

    //if the string doesn't contain any space then it will cut without word basis.
    $string = $endPoint? substr($stringCut, 0, $endPoint) : substr($stringCut, 0);
    $string .= '... <a href="/this/story">Read More</a>';
}
echo $string;

You can tweak it further but it gets the job done in production.

Natalie Hedström
  • 2,607
  • 3
  • 25
  • 36
webbiedave
  • 48,414
  • 8
  • 88
  • 101
  • 1
    Thanks for the Answer , but after using strip_tags($strings) , the html is lost , how can I after reducing the string length retain the html back which was previously present – harshal Sep 11 '15 at 11:54
  • @harshal The `strip_tags` is in there because most sites I've worked on just want plain text blurbs (that then link to the page with the fully formatted article). If you want to retain the HTML you can use an XML parser to grab the text values of each sub-element, accumulating the character count while also checking for possible tag breakage. That is a much more complex problem and well beyond the scope of this question. – webbiedave Oct 01 '15 at 02:29
  • @Webbiedave what is the href here?? sorry i did not understand it thats why i asked?? should it point to self page or something else? – Mike Ross Oct 08 '15 at 00:21
  • "make sure it ends in a word so assassinate doesn't become ass... " ROFL – devDeejay May 08 '17 at 17:29
  • 1
    Three dots will be wont be added to a result if the first statement in a ternary check is true. So, brackets should be added around ternary check `$teaser = ($endPoint ? substr($stringCut, 0, $endPoint) : substr($stringCut, 0)) . ' ...';` Beside that, it's nice solution. – azurecorn Jul 06 '18 at 13:45
13
$num_words = 101;
$words = array();
$words = explode(" ", $original_string, $num_words);
$shown_string = "";

if(count($words) == 101){
   $words[100] = " ... ";
}

$shown_string = implode(" ", $words);
bcosca
  • 17,371
  • 5
  • 40
  • 51
Brian H
  • 833
  • 1
  • 5
  • 12
  • you can change the "..." to a link to more information, or make it open a div with the whole block of text on the same page. Lots of options.. – Brian H Nov 23 '10 at 17:03
  • please format your answer next time. there are appropriate buttons at the top of the textarea – bcosca Nov 23 '10 at 17:05
  • As this is a formatting issue, it's preferred to limit based on character count rather than word count as words will be of varying length. – webbiedave Nov 23 '10 at 17:38
  • @stillstanding: Thanks, I didn't realize it has removed the returns until after I had posted. I assumed it would be shown as typed. – Brian H Nov 23 '10 at 18:06
12

There is an appropriate PHP function: substr_replace($text, $replacement, $start).

For your case, because you already know all the possibilities of the text length (100, 1000 or 10000 words), you can simply use that PHP function like this:

echo substr_replace($your_text, "...", 20);

PHP will automatically return a 20 character only text with ....

Se the documentation by clicking here.

nekiala
  • 450
  • 9
  • 21
5

I have combine two different answers:

  1. Limit the characters
  2. Complete HTML missing tags

    $string = strip_tags($strHTML);
    $yourText = $strHTML;
    if (strlen($string) > 350) {
        $stringCut = substr($post->body, 0, 350);
        $doc = new DOMDocument();
        $doc->loadHTML($stringCut);
        $yourText = $doc->saveHTML();
    }
    $yourText."...<a href=''>View More</a>"
    
Jonas Czech
  • 12,018
  • 6
  • 44
  • 65
Waqas Ahmed
  • 311
  • 3
  • 6
3

Simple use this to strip the text :

echo strlen($string) >= 500 ? 
substr($string, 0, 490) . ' <a href="link/to/the/entire/text.htm">[Read more]</a>' : 
$string;

Edit and finally :

function split_words($string, $nb_caracs, $separator){
    $string = strip_tags(html_entity_decode($string));
    if( strlen($string) <= $nb_caracs ){
        $final_string = $string;
    } else {
        $final_string = "";
        $words = explode(" ", $string);
        foreach( $words as $value ){
            if( strlen($final_string . " " . $value) < $nb_caracs ){
                if( !empty($final_string) ) $final_string .= " ";
                $final_string .= $value;
            } else {
                break;
            }
        }
        $final_string .= $separator;
    }
    return $final_string;
}

Here separator is the href link to read more ;)

CrazyMax
  • 781
  • 1
  • 11
  • 24
2
<?php $string = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.";
if (strlen($string) > 25) {
$trimstring = substr($string, 0, 25). ' <a href="#">readmore...</a>';
} else {
$trimstring = $string;
}
echo $trimstring;
//Output : Lorem Ipsum is simply dum [readmore...][1]
?>
1

This method will not truncate a word in the middle.

list($output)=explode("\n",wordwrap(strip_tags($str),500),1);
echo $output. ' ... <a href="#">Read more</a>';
bcosca
  • 17,371
  • 5
  • 40
  • 51
1

Limit words in text:

function limitTextWords($content = false, $limit = false, $stripTags = false, $ellipsis = false) 
{
    if ($content && $limit) {
        $content = ($stripTags ? strip_tags($content) : $content);
        $content = explode(' ', $content, $limit+1);
        array_pop($content);
        if ($ellipsis) {
            array_push($content, '...');
        }
        $content = implode(' ', $content);
    }
    return $content;
}

Limit chars in text:

function limitTextChars($content = false, $limit = false, $stripTags = false, $ellipsis = false) 
{
    if ($content && $limit) {
        $content  = ($stripTags ? strip_tags($content) : $content);
        $ellipsis = ($ellipsis ? "..." : $ellipsis);
        $content  = mb_strimwidth($content, 0, $limit, $ellipsis);
    }
    return $content;
}

Use:

$text = "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout.";
echo limitTextWords($text, 5, true, true);
echo limitTextChars($text, 5, true, true);
Alexandru Sirbu
  • 179
  • 1
  • 10
0

Another method: insert the following in your theme's function.php file.

remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'custom_trim_excerpt');

function custom_trim_excerpt($text) { // Fakes an excerpt if needed
global $post;
if ( '' == $text ) {
$text = get_the_content('');
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$text = strip_tags($text);
$excerpt_length = x;
$words = explode(' ', $text, $excerpt_length + 1);
if (count($words) > $excerpt_length) {
array_pop($words);
array_push($words, '...');
$text = implode(' ', $words);
}
}
return $text;
}

You can use this.

csehasib
  • 365
  • 3
  • 7
0
<?php
     $images_path = 'uploads/adsimages/';
             $ads = mysql_query("select * from tbl_postads ORDER BY ads_id DESC limit 0,5 ");
                    if(mysql_num_rows($ads)>0)
                    {
                        while($ad = mysql_fetch_array($ads))

                        {?>


     <div style="float:left; width:100%; height:100px;">
    <div style="float:left; width:40%; height:100px;">
      <li><img src="<?php echo $images_path.$ad['ads_image']; ?>" width="100px" height="50px" alt="" /></li>
      </div>

       <div style="float:left; width:60%; height:100px;">
      <li style="margin-bottom:4%;"><?php echo substr($ad['ads_msg'],0,50);?><br/> <a href="index.php?page=listing&ads_id=<?php echo $_GET['ads_id'];?>">read more..</a></li>
      </div>

     </div> 

    <?php }}?>
josliber
  • 43,891
  • 12
  • 98
  • 133
0

Basically, you need to integrate a word limiter (e.g. something like this) and use something like shadowbox. Your read more link should link to a PHP script that displays the entire article. Just setup Shadowbox on those links and you're set. (See instructions on their site. Its easy.)

simshaun
  • 21,263
  • 1
  • 57
  • 73
0

I Guess this will help you fix your problem please check under given Function : trims text to a space then adds ellipses if desired

  • @param string $input text to trim

    • @param int $length in characters to trim to
    • @param bool $ellipses if ellipses (...) are to be added
    • @param bool $strip_html if html tags are to be stripped
    • @return string

      function trim_text($input, $length, $ellipses = true, $strip_html = true) {
      //strip tags, if desired
      if ($strip_html) {
          $input = strip_tags($input);
      }//no need to trim, already shorter than trim length
      if (strlen($input) <= $length) {
          return $input;
      }
      
      //find last space within length
      $last_space = strrpos(substr($input, 0, $length), ' ');
      $trimmed_text = substr($input, 0, $last_space);
      
      //add ellipses (...)
      if ($ellipses) {
          $trimmed_text .= '...';
      }
      
      return $trimmed_text;}
      
-1

This worked for me.

// strip tags to avoid breaking any html
$string = strip_tags($string);
if (strlen($string) > 500) {

    // truncate string
    $stringCut = substr($string, 0, 500);
    $endPoint = strrpos($stringCut, ' ');

    //if the string doesn't contain any space then it will cut without word basis.
    $string = $endPoint? substr($stringCut, 0, $endPoint) : substr($stringCut, 0);
    $string .= '... <a href="/this/story">Read More</a>';
}
echo $string;

Thanks @webbiedave

Murtaza JAFARI
  • 674
  • 7
  • 10