Shorten a text string

Hi @ all !

Sometimes I’d to preview a text string and add three dots at its end. I’m wondering if a such function exist into the framework. If no, I’d like to suggest you to add it.

Here is an already done example :

http://www.totallyphp.co.uk/code/shorten_a_text_string.htm

Where do you suggest this get added? I do not see an appropriate place for it in the framework. Recently Qiang added a string helper but he later removed it. That was the only place it would have fitted in.

Best route for you is to add it to your appliction.

You can make your own helper class and add to it something like this:

ShortenText

Then use it in your application as jayrulez suggests!..

I suggest that as an additional (and optional) argument that can be passed to CHtml::encode().

Something like :


public static string encode(string $text,[int $maxlenght = false])

where maxlength means how many characters to display before the three dots (…).

Of course if maxlength is not set, then the text will not be Shorten.

Sorry, I don’t speak english well and I hope you’ll understand.

I think every feature request should be taken into consideration, You should add a ticket in the Yii google code project for the developers to take a look at it.

@saegeek:

That’s a very specific request that’s not really related to encode(). In the same way you could want a third parameter $convertToUpperCase and a fourth $enableWordWrap. I doubt that you’ll ever see that implemented - framework components should stay lean and focused.

Instead like jayrulez suggests: Create your own library to wrap helper calls and perform additional actions.

Write a string helper class, make an extension, share it with community! ;)

And I agree with Mike. CHtml is inappropriate class for such functions.

So why you don’t add a new static class to handle strings. Something like CstrTools::Shorten() ?

Create a ticket on the googlecode project asking the devs to add this file again

http://code.google.com/p/yii/source/diff?spec=svn1992&r=1992&format=side&path=/trunk/framework/utils/CStringHelper.php

and add it to it.

Issue added :

http://code.google.com/p/yii/issues/detail?id=1132&colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Stars%20Summary#makechanges

i found a function on the internet that will shorten your text and will keep the HTML tags if you want.

usage:




Yii::import('system.web.helpers.CString');


echo CString::truncate('your string or html here', 100);



CString helper




<?php


class CString

{

    function truncate($text = '', $length = 100, $suffix = 'read more&hellip;', $isHTML = true){

        $i = 0;

        $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);

                if($t[0] != '/')

                    $tags[] = $t;

                elseif(end($tags) == substr($t, 1))

                    array_pop($tags);

                $i += $o[1][1] - $o[0][1];

            }

        }

       

        $output = substr($text, 0, $length = min(strlen($text),  $length + $i)) . (count($tags = array_reverse($tags)) ? '</' . implode('></', $tags) . '>' : '');

       

        // Get everything until last space

        $one = substr($output, 0, strrpos($output, " "));

        // Get the rest

        $two = substr($output, strrpos($output, " "), (strlen($output) - strrpos($output, " ")));

        // Extract all tags from the last bit

        preg_match_all('/<(.*?)>/s', $two, $tags);

        // Add suffix if needed

        if (strlen($text) > $length) { $one .= '&nbsp;' . $suffix; } else { $one .= '&nbsp;read'; }

        // Re-attach tags

        $output = $one . implode($tags[0]);

       

        return $output;

    }

}



Hi,

This function provides the exact truncation of html text with specified length. You can modify according to your requirements


function printTruncated($maxLength, $html)

{

    $printedLength = 0;

    $position = 0;

    $tags = array();


    while ($printedLength < $maxLength && preg_match('{</?([a-z]+)[^>]*>|&#?[a-zA-Z0-9]+;}', $html, $match, PREG_OFFSET_CAPTURE, $position))

    {

        list($tag, $tagPosition) = $match[0];


        // Print text leading up to the tag.

        $str = substr($html, $position, $tagPosition - $position);

        if ($printedLength + strlen($str) > $maxLength)

        {

            print(substr($str, 0, $maxLength - $printedLength));

            $printedLength = $maxLength;

            break;

        }


        print($str);

        $printedLength += strlen($str);


        if ($tag[0] == '&')

        {

            // Handle the entity.

            print($tag);

            $printedLength++;

        }

        else

        {

            // Handle the tag.

            $tagName = $match[1][0];

            if ($tag[1] == '/')

            {

                // This is a closing tag.


                $openingTag = array_pop($tags);

                assert($openingTag == $tagName); // check that tags are properly nested.


                print($tag);

            }

            else if ($tag[strlen($tag) - 2] == '/')

            {

                // Self-closing tag.

                print($tag);

            }

            else

            {

                // Opening tag.

                print($tag);

                $tags[] = $tagName;

            }

        }


        // Continue after the tag.

        $position = $tagPosition + strlen($tag);

    }


    // Print any remaining text.

    if ($printedLength < $maxLength && $position < strlen($html))

        print(substr($html, $position, $maxLength - $printedLength));


    // Close any open tags.

    while (!empty($tags))

        printf('</%s>', array_pop($tags));

}

This is a very old topic, but i’m wondering if is there any option to shorten the text inside a dropDownList.

the idea is to have a limited dropdown with 50 chars and if the dropdown values contain more than 50 chars the values should show something like

"abcdededefefefe…fafas" or "asdadasdasdasdasda…"

Any idea or option that I missed?

Something like this?


$string = (strlen($string) > 50) ? substr($string,0,47).'...' : $string;



So you will get a string of max 50 characters; either 50 (or less) normal characters or 47 characters followed by ‘…’

substr incorrectly works with utf-8 encoding. First of all, one should use mb_subst instead. Second, point it to correct encoding:


mb_substr($string, 0, 47, Yii::app()->charset)

Hi

I recommend that you read my Wiki page regarding this:

http://www.yiiframework.com/wiki/454/limit-a-cgridview-field-to-some-preset-length/

I propose to extend Yii’s formatter. Once that is done it is easy to format grid columns with it or use the formatter explicitally to do the formatting.

Kind regards

Mario