Smarty Forum Index Smarty
The discussions here are for Smarty, a template engine for the PHP programming language.

HTML Truncate plugin

 
Post new topic   Reply to topic    Smarty Forum Index -> Plugins
View previous topic :: View next topic  
Author Message
scompt
Smarty n00b


Joined: 19 Jun 2003
Posts: 1

PostPosted: Thu Jun 19, 2003 3:39 pm    Post subject: HTML Truncate plugin Reply with quote

Hello,
I found myself in need of a modifier to truncate an HTML string, maintaining all of the tags and such. I couldn't immediate find an existing one, so I ported some javascript code I found to PHP & Smarty. Here it is, in case anybody else finds this useful.

[php:1:a6726020e4]
<?php
/*
* Smarty plugin
*
-------------------------------------------------------------
* File: modifier.html_substr.php
* Type: modifier
* Name: html_substr
* Version: 1.0
* Date: June 19th, 2003
* Purpose: Cut a string preserving any tag nesting and matching.
* Install: Drop into the plugin directory.
* Author: Original Javascript Code: Benjamin Lupu <lupufr@aol.com>
* Translation to PHP & Smarty: Edward Dale <scompt@scompt.com>
*
-------------------------------------------------------------
*/
function smarty_modifier_html_substr($string, $length)
{
if( !empty( $string ) && $length>0 ) {
$isText = true;
$ret = "";
$i = 0;

$currentChar = "";
$lastSpacePosition = -1;
$lastChar = "";

$tagsArray = array();
$currentTag = "";
$tagLevel = 0;

$noTagLength = strlen( strip_tags( $string ) );

// Parser loop
for( $j=0; $j<strlen( $string ); $j++ ) {

$currentChar = substr( $string, $j, 1 );
$ret .= $currentChar;

// Lesser than event
if( $currentChar == "<") $isText = false;

// Character handler
if( $isText ) {

// Memorize last space position
if( $currentChar == " " ) { $lastSpacePosition = $j; }
else { $lastChar = $currentChar; }

$i++;
} else {
$currentTag .= $currentChar;
}

// Greater than event
if( $currentChar == ">" ) {
$isText = true;

// Opening tag handler
if( ( strpos( $currentTag, "<" ) !== FALSE ) &&
( strpos( $currentTag, "/>" ) === FALSE ) &&
( strpos( $currentTag, "</") === FALSE ) ) {

// Tag has attribute(s)
if( strpos( $currentTag, " " ) !== FALSE ) {
$currentTag = substr( $currentTag, 1, strpos( $currentTag, " " ) - 1 );
} else {
// Tag doesn't have attribute(s)
$currentTag = substr( $currentTag, 1, -1 );
}

array_push( $tagsArray, $currentTag );

} else if( strpos( $currentTag, "</" ) !== FALSE ) {

array_pop( $tagsArray );
}

$currentTag = "";
}

if( $i >= $length) {
break;
}
}

// Cut HTML string at last space position
if( $length < $noTagLength ) {
if( $lastSpacePosition != -1 ) {
$ret = substr( $string, 0, $lastSpacePosition );
} else {
$ret = substr( $string, $j );
}
}

// Close broken XHTML elements
while( sizeof( $tagsArray ) != 0 ) {
$aTag = array_pop( $tagsArray );
$ret .= "</" . $aTag . ">\n";
}

} else {
$ret = "";
}

return( $ret );
}

/* vim: set expandtab: */

?>
[/php:1:a6726020e4]

It is called like so:
Code:

{$htmlString|html_substr:100}


Edward
Back to top
View user's profile Send private message Visit poster's website
AZTEK
Smarty Pro


Joined: 16 Apr 2003
Posts: 235
Location: Purdue University

PostPosted: Thu Jun 19, 2003 6:17 pm    Post subject: Reply with quote

Nice I will have to start using this
_________________
"Imagine a school with children that can read and write, but with teachers who cannot, and you have a metaphor of the Information Age in which we live." -Peter Cochrane
Back to top
View user's profile Send private message Visit poster's website
bl4ckh4wk
Smarty n00b


Joined: 19 Jul 2003
Posts: 1

PostPosted: Sat Jul 19, 2003 2:16 pm    Post subject: Reply with quote

scompt, that really is a nice plugin. I added some lines to make it more useable with news-scripts.

[php:1:eda6c48e38]
<?php
/*
* Smarty plugin
*
-------------------------------------------------------------
* File: modifier.html_substr.php
* Type: modifier
* Name: html_substr
* Version: 1.0
* Date: June 19th, 2003
* Purpose: Cut a string preserving any tag nesting and matching.
* Install: Drop into the plugin directory.
* Author: Original Javascript Code: Benjamin Lupu <lupufr@aol.com>
* Translation to PHP & Smarty: Edward Dale <scompt@scompt.com>
* Modification to add a string: Sebastian Kuhlmann <sebastiankuhlmann@web.de>
*
-------------------------------------------------------------
*/
function smarty_modifier_html_substr($string, $length, $addstring="")
{
$addstring = " " . $addstring;

if (strlen($string) > $length) {
if( !empty( $string ) && $length>0 ) {
$isText = true;
$ret = "";
$i = 0;

$currentChar = "";
$lastSpacePosition = -1;
$lastChar = "";

$tagsArray = array();
$currentTag = "";
$tagLevel = 0;

$noTagLength = strlen( strip_tags( $string ) );

// Parser loop
for( $j=0; $j<strlen( $string ); $j++ ) {

$currentChar = substr( $string, $j, 1 );
$ret .= $currentChar;

// Lesser than event
if( $currentChar == "<") $isText = false;

// Character handler
if( $isText ) {

// Memorize last space position
if( $currentChar == " " ) { $lastSpacePosition = $j; }
else { $lastChar = $currentChar; }

$i++;
} else {
$currentTag .= $currentChar;
}

// Greater than event
if( $currentChar == ">" ) {
$isText = true;

// Opening tag handler
if( ( strpos( $currentTag, "<" ) !== FALSE ) &&
( strpos( $currentTag, "/>" ) === FALSE ) &&
( strpos( $currentTag, "</") === FALSE ) ) {

// Tag has attribute(s)
if( strpos( $currentTag, " " ) !== FALSE ) {
$currentTag = substr( $currentTag, 1, strpos( $currentTag, " " ) - 1 );
} else {
// Tag doesn't have attribute(s)
$currentTag = substr( $currentTag, 1, -1 );
}

array_push( $tagsArray, $currentTag );

} else if( strpos( $currentTag, "</" ) !== FALSE ) {
array_pop( $tagsArray );
}

$currentTag = "";
}

if( $i >= $length) {
break;
}
}

// Cut HTML string at last space position
if( $length < $noTagLength ) {
if( $lastSpacePosition != -1 ) {
$ret = substr( $string, 0, $lastSpacePosition );
} else {
$ret = substr( $string, $j );
}
}

// Close broken XHTML elements
while( sizeof( $tagsArray ) != 0 ) {
$aTag = array_pop( $tagsArray );
$ret .= "</" . $aTag . ">\n";
}

} else {
$ret = "";
}

// only add string if text was cut
if ( strlen($string) > $length ) {
return( $ret.$addstring );
}
else {
return ( $res );
}
}
else {
return ( $string );
}
}

/* vim: set expandtab: */

?> [/php:1:eda6c48e38]

Called now with
Code:

{$htmlString|html_substr:<lengh>:<string_to_add>}


Sebastian
Back to top
View user's profile Send private message
stopsatgreen
Smarty n00b


Joined: 21 Jul 2008
Posts: 1

PostPosted: Mon Jul 21, 2008 1:59 pm    Post subject: Changing appended string behaviour Reply with quote

I've just found this five-year-old script which gives me the functionality I'm after - that is, to truncate text without losing HTML markup from the end - and it seems to work almost perfectly.

The one drawback I've found (in the second version) is that the text which is appended to the end - $addstring - gets added after the closing HTML container, which is far from ideal.

Could anybody show me where this variable should be returned to fit inside the HTML? Also, is the code in this example safe, considering its age?
Back to top
View user's profile Send private message
jaslorax
Smarty n00b


Joined: 05 Jun 2009
Posts: 4

PostPosted: Thu Jan 14, 2010 1:36 am    Post subject: Slightly Improved Reply with quote

I took the code and made it work as a UDT (User Defined Tag) I call Truncate Better on CMSMS (CMS Made Simple) . . . I added a "read more" link with variable text and put the user specified "addstring" before the closing tag if it matches specific elements like "p" or "div". It works great for me in CMSMS but had to do a rough conversion to post it here as a drop in. Should work but is untested in this form . . . At the very least you can see how I changed the "while" loop to include the addstring and link . . .

<code>
<?php
/*
* Smarty plugin
* http://www.smarty.net/forums/viewtopic.php?t=533
-----------------------------------------------------
* File: modifier.html_substr.php
* Type: modifier
* Name: html_substr
* Version: 1.2
* Date: January 13th, 2010
* Purpose: Cut a string preserving any tag nesting and matching.
* Install: Drop into the plugin directory.
* Author: Original Javascript Code: Benjamin Lupu <lupufr@aol.com>
* Translation to PHP & Smarty: Edward Dale <scompt@scompt.com>
* Modification to add a string: Sebastian Kuhlmann <sebastiankuhlmann@web.de>
* Modification to add user defined closing text before closing tag if tag matches specified elements and added read more link with variable text:
* Avi J Liebowitz avij.com
* Example Usage {$htmlString|html_substr:<lengh>:<string_to_add>:<link>:<link_text>}
-------------------------------------------------------------
*/
function smarty_modifier_html_substr($string, $length, $addstring, $link, $link_text)
{

// only execute if text is longer than desired length
if (strlen($string) > $length) {
if( !empty( $string ) && $length>0 ) {
$isText = true;
$ret = "";
$i = 0;

$currentChar = "";
$lastSpacePosition = -1;
$lastChar = "";

$tagsArray = array();
$currentTag = "";
$tagLevel = 0;

$noTagLength = strlen( strip_tags( $string ) );

// Parser loop
for( $j=0; $j<strlen( $string ); $j++ ) {

$currentChar = substr( $string, $j, 1 );
$ret .= $currentChar;

// Lesser than event
if( $currentChar == "<") $isText = false;

// Character handler
if( $isText ) {

// Memorize last space position
if( $currentChar == " " ) { $lastSpacePosition = $j; }
else { $lastChar = $currentChar; }

$i++;
} else {
$currentTag .= $currentChar;
}

// Greater than event
if( $currentChar == ">" ) {
$isText = true;

// Opening tag handler
if( ( strpos( $currentTag, "<" ) !== FALSE ) &&
( strpos( $currentTag, "/>" ) === FALSE ) &&
( strpos( $currentTag, "</") === FALSE ) ) {

// Tag has attribute(s)
if( strpos( $currentTag, " " ) !== FALSE ) {
$currentTag = substr( $currentTag, 1, strpos( $currentTag, " " ) - 1 );
} else {
// Tag doesn't have attribute(s)
$currentTag = substr( $currentTag, 1, -1 );
}

array_push( $tagsArray, $currentTag );

} else if( strpos( $currentTag, "</" ) !== FALSE ) {
array_pop( $tagsArray );
}

$currentTag = "";
}

if( $i >= $length) {
break;
}
}

// Cut HTML string at last space position
if( $length < $noTagLength ) {
if( $lastSpacePosition != -1 ) {
$ret = substr( $string, 0, $lastSpacePosition );
} else {
$ret = substr( $string, $j );
}
}

// Close broken XHTML elements
while( sizeof( $tagsArray ) != 0 ) {
if ( sizeof( $tagsArray ) > 1 ) {
$aTag = array_pop( $tagsArray );
$ret .= "</" . $aTag . ">\n";
}
// You may add more tags here to put the link and added text before the closing tag
elseif ($aTag = 'p' || 'div') {
$aTag = array_pop( $tagsArray );
$ret .= $addstring . "<a href=\"". $link . "\" alt=\"". $link_text . "\">" . $link_text . "</a></" . $aTag . ">\n";
}
else {
$aTag = array_pop( $tagsArray );
$ret .= "</" . $aTag . ">" . $addstring . "<a href=\"". $link . "\" alt=\"". $link_text . "\">" . $link_text . "</a>\n";
}
}

} else {
$ret = "";
}

return( $ret );
}
else {
return ( $string );
}
}
?>
</code>

GoodLuckSigned
jaslorax
Back to top
View user's profile Send private message
Jerc
Smarty Rookie


Joined: 26 Jan 2010
Posts: 30
Location: Slovenia / Ljubljana

PostPosted: Fri Jan 14, 2011 9:21 am    Post subject: Reply with quote

Thanks for the script. I was just planning to create it during weekend.

@jaslorax: I've little changed your script. The part where you add additional string and url. It didn't work, if there were not opened tag.

Code:

function smarty_modifier_html_substr($string, $length, $addstring = '', $link = '', $link_text = '') {
....

if (sizeof( $tagsArray ) != 0) {
   if ($addstring != '') {
      $ret .= $addstring;
   }
   if ($link != '' && $link_text != '') {
      $ret .= "<a href=\"". $link . "\" alt=\"". $link_text . "\">" . $link_text . "</a>";
   }
} else {
   // Close broken XHTML elements
   while( sizeof( $tagsArray ) != 0 ) {
      if ( sizeof( $tagsArray ) > 1 ) {
         $aTag = array_pop( $tagsArray );
         $ret .= "</" . $aTag . ">";
      }
      // You may add more tags here to put the link and added text before the closing tag
      elseif ($aTag = 'p' || 'div') {
         $aTag = array_pop( $tagsArray );
         if ($addstring != '') {
            $ret .= $addstring;
         }
         if ($link != '' && $link_text != '') {
            $ret .= "<a href=\"". $link . "\" alt=\"". $link_text . "\">" . $link_text . "</a>";
         }
         $ret .= "</" . $aTag . ">";
      }
      else {
         $aTag = array_pop( $tagsArray );
         $ret .= "</" . $aTag . ">";
         if ($addstring != '') {
            $ret .= $addstring;
         }
         if ($link != '' && $link_text != '') {
            $ret .= "<a href=\"". $link . "\" alt=\"". $link_text . "\">" . $link_text . "</a>";
         }
      }
   }
}
...
Back to top
View user's profile Send private message
Matheo
Smarty n00b


Joined: 26 Nov 2009
Posts: 2

PostPosted: Tue Mar 29, 2011 7:40 am    Post subject: License holder :( Reply with quote

It's sad that no flexible license was used on this code, so it can't be used on LGPL frameworks Sad
Back to top
View user's profile Send private message
nhantam
Smarty n00b


Joined: 02 Dec 2011
Posts: 2
Location: Ho Chi Minh

PostPosted: Fri Dec 16, 2011 3:57 am    Post subject: Reply with quote

I use
{$title|html_substr:"30":".."}
or
{$itcgArr.cgTitle|html_substr:30:'..'}

It not run with smarty 2.6.26 but it run with version 2.6.25.
How do I fix ?
Back to top
View user's profile Send private message Send e-mail Yahoo Messenger
bricef
Smarty n00b


Joined: 19 Oct 2011
Posts: 2

PostPosted: Thu Mar 08, 2012 11:13 am    Post subject: Reply with quote

Hello,

Thanks for this plugin, i made some modification and cleaning to the code if you want :

Code:
<?php
/*
* Smarty plugin
* http://www.smarty.net/forums/viewtopic.php?t=533
-----------------------------------------------------
* File: modifier.html_substr.php
* Type: modifier
* Name: html_substr
* Version: 1.2
* Date: January 13th, 2010
* Purpose: Cut a string preserving any tag nesting and matching.
* Install: Drop into the plugin directory.
* Author: Original Javascript Code: Benjamin Lupu <lupufr@aol.com>
* Translation to PHP & Smarty: Edward Dale <scompt@scompt.com>
* Modification to add a string: Sebastian Kuhlmann <sebastiankuhlmann@web.de>
* Modification to add user defined closing text before closing tag if tag matches specified elements and added read more link with variable text:
* Avi J Liebowitz avij.com
 * Clean up by Brice Favre <brice.favre@blogspirit.com>
* Example Usage {$htmlString|html_substr:<lengh>:<string_to_add>:<link>:<link_text>}
-------------------------------------------------------------
*/
function smarty_modifier_html_substr($string, $length, $addstring, $link, $link_text) {
    // only execute if text is longer than desired length
    if (strlen($string) > $length) {
        if( !empty( $string ) && $length > 0 ) {
            $isText = true;
            $ret = "";
            $i = 0;

            $lastSpacePosition = -1;

            $tagsArray = array();
            $currentTag = "";

            $noTagLength = strlen(strip_tags($string));

            // Parser loop
            $string_length = strlen($string);
            for($j = 0 ; $j < $string_length ; $j++) {

                $currentChar = substr( $string, $j, 1 );
                $ret .= $currentChar;

                // Lesser than event
                if( $currentChar == "<") $isText = false;

                // Character handler
                if( $isText ) {

                    // Memorize last space position
                    if( $currentChar == " " ) {
                        $lastSpacePosition = $j;
                    }
                    else {
                        $lastChar = $currentChar;
                    }

                    $i++;
                } else {
                    $currentTag .= $currentChar;
                }

                // Greater than event
                if( $currentChar == ">" ) {
                    $isText = true;

                    // Opening tag handler
                    if( ( strpos( $currentTag, "<" ) !== false) &&
                            ( strpos( $currentTag, "/>" ) === false) &&
                            ( strpos( $currentTag, "</") === false) ) {

                        // Tag has attribute(s)
                        if( strpos( $currentTag, " " ) !== false ) {
                            $currentTag = substr( $currentTag, 1, strpos( $currentTag, " " ) - 1 );
                        } else {
                            // Tag doesn't have attribute(s)
                            $currentTag = substr( $currentTag, 1, -1 );
                        }

                        array_push( $tagsArray, $currentTag );

                    } else if( strpos( $currentTag, "</" ) !== false ) {
                        array_pop( $tagsArray );
                    }

                    $currentTag = "";
                }

                if( $i >= $length) {
                    break;
                }
            }

            // Cut HTML string at last space position
            if( $length < $noTagLength ) {
                if( $lastSpacePosition != -1 ) {
                    $ret = substr( $string, 0, $lastSpacePosition );
                } else {
                    $ret = substr( $string, $j );
                }
            }

            // Close broken XHTML elements
            while( count( $tagsArray ) != 0 ) {
                if ( count( $tagsArray ) > 1 ) {
                    $aTag = array_pop( $tagsArray );
                    $ret .= "</" . $aTag . ">\n";
                }
                // You may add more tags here to put the link and added text before the closing tag
                elseif ($aTag = 'p' || 'div') {
                    $aTag = array_pop( $tagsArray );
                    $ret .= $addstring . "<a href=\"". $link . "\" alt=\"". $link_text . "\">" . $link_text . "</a></" . $aTag . ">\n";
                }
                else {
                    $aTag = array_pop( $tagsArray );
                    $ret .= "</" . $aTag . ">" . $addstring . "<a href=\"". $link . "\" alt=\"". $link_text . "\">" . $link_text . "</a>\n";
                }
            }
        } else {
            $ret = "";
        }

        return $ret;
    }
    else {
        return $string;
    }
}
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Smarty Forum Index -> Plugins All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP