'Cut out HTML tags from Smarty variable

I was building a Smarty template. All was fine before i checked the validation.

The Truncate of the Description is included but the end tag will not be added. Any tag addings will not help.

The truncate is called like

{$products_data.PRODUCTS_DESCRIPTION|truncate:300}

The Description has more than 300 characters and it starts and ends with p tags. After the truncate has cut it then i have just the starting tag <p>.

Is there a way to cut HTML tags out for truncate?



Solution 1:[1]

i ran into the same problem during a project and found a great smarty modifier called "html_substr" written by Benjamin Lupu/Edward Dale. Simply add a new php file called "modifier.html_substr.php" into the smarty/libs/plugins directory:

(Sorry - i don' remember the source so I'm just posting the whole function here):

<?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 <[email protected]>
* Translation to PHP & Smarty: Edward Dale <[email protected]>
* Modification to add a string: Sebastian Kuhlmann <[email protected]>
* Modification to put the added string before closing <p> or <li> tags by Peter Carter http://www.podhawk.com
-------------------------------------------------------------
*/
function smarty_modifier_html_substr($string, $length, $addstring="")
{

//some nice italics for the add-string
 if (!empty($addstring)) $addstring = "<i> " . $addstring . "</i>";

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

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

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

        $addstringAdded = false;

        $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 );
                // if a <p> or <li> tag needs to be closed, put the add-string in first
                if (($aTag == "p" || $aTag == "li") && strlen($string) > $length) {
                $ret .= $addstring;
                $addstringAdded = true;
                }
            $ret .= "</" . $aTag . ">\n";
            }

        } else {
        $ret = "";
        }

    // if we have not added the add-string already 
    if ( strlen($string) > $length && $addstringAdded == false) {
        return( $ret.$addstring );
        }
        else {
        return ( $ret );
        }
    }
    else {
    return ( $string );
    }
}
?>

Usage:

{$products_data.PRODUCTS_DESCRIPTION|html_substr:300:' ...'}

Solution 2:[2]

I looked for a solution to truncate the text without impacting the html tags. I wanted to truncate the text of the short description to 300 characters and keep my html.

So I replaced

{$product.description nofilter}

By

{Tools::truncateString($product.description, 300) nofilter}

The solution works very well on prestashop 1.7

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Toulousain