1

我正在构建一个 Smarty 模板。在我检查验证之前一切都很好。

包含描述的截断,但不会添加结束标记。任何标签添加都无济于事。

截断被称为

{$products_data.PRODUCTS_DESCRIPTION|truncate:300}

描述有 300 多个字符,并以p标签开头和结尾。截断后,我只有开始标签<p>

有没有办法将 HTML 标签剪掉以进行截断?

4

3 回答 3

5

我在一个项目中遇到了同样的问题,并发现了一个由 Benjamin Lupu/Edward Dale 编写的名为“html_substr”的出色修饰符。只需在 smarty/libs/plugins 目录中添加一个名为“modifier.html_substr.php”的新 php 文件:

(对不起 - 我不记得来源所以我只是在这里发布整个功能):

<?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 <hide@address.com>
* Translation to PHP & Smarty: Edward Dale <hide@address.com>
* Modification to add a string: Sebastian Kuhlmann <hide@address.com>
* 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 );
    }
}
?>

用法:

{$products_data.PRODUCTS_DESCRIPTION|html_substr:300:' ...'}
于 2013-01-07T12:36:07.780 回答
3

过滤掉html标签,截断文本,然后放回html标签是相当困难的。我建议您使用 strip_tags 删除所有 html 标签,然后截断生成的文本。如果需要,您可以将剩下的内容嵌入到 <p> 标记中:

{$products_data.PRODUCTS_DESCRIPTION|strip_tags|truncate:300}

于 2013-01-06T13:55:56.467 回答
0

我寻找一种在不影响 html 标签的情况下截断文本的解决方案。我想将简短描述的文本截断为 300 个字符并保留我的 html。

所以我换了

{$product.description nofilter}

经过

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

该解决方案在 prestashop 1.7 上运行良好

于 2022-02-18T09:29:14.900 回答