使用 cn_substr() 函数
DedeCMS 提供了一个非常核心的字符串截取函数 cn_substr(),专门用于处理中文字符串,可以避免因一个汉字占三个字节而导致的截断乱码问题。

(图片来源网络,侵删)
函数语法:
cn_substr($str, $start=0, $slen=80, $charset='utf-8')
参数说明:
$str: 需要截取的原始字符串。$start(可选): 开始截取的位置,从 0 开始,默认为 0。$slen(可选): 需要截取的字符长度,默认为 80。$charset(可选): 字符编码,默认为 'utf-8'。
在列表页 (list_*.php) 截取文章描述
在列表页,我们通常需要循环输出文章列表,并对每篇文章的 description 进行截取。
原始代码可能长这样:

(图片来源网络,侵删)
{dede:list pagesize='10'}
<li>
<a href="[field:arcurl/]">[field:title/]</a>
<p>[field:description/]</p> <!-- 这里可能输出很长的描述 -->
</li>
{/dede:list}
修改后,使用 cn_substr() 截取:
假设我们希望描述最多显示 50 个字符。
{dede:list pagesize='10'}
<li>
<a href="[field:arcurl/]">[field:title/]</a>
<p>[field:description function='cn_substr(@me, 50)'/]</p>
</li>
{/dede:list}
代码解析:
[field:description ...]: 这是调用description字段的标准写法。function='...': 这是调用 PHP 函数的语法。cn_substr(@me, 50): 这是函数调用。cn_substr: 函数名。@me: 这是 DedeCMS 模板引擎中的一个特殊变量,代表当前标签的原始值。@me就代表[field:description/]的原始内容。50: 我们希望截取的字符长度。
进阶:添加省略号
截取后,如果原文比截取长度长,我们通常希望加上 "..." 来表示内容被截断了,我们可以结合 PHP 的 strlen() 函数和三元运算符来实现。

(图片来源网络,侵删)
{dede:list pagesize='10'}
<li>
<a href="[field:arcurl/]">[field:title/]</a>
<p>
[field:description function='
$description = cn_substr(@me, 50);
if(strlen(cn_substr(@me, 50)) < strlen(@me)) {
$description .= "...";
}
echo $description;
'/]
</p>
</li>
{/dede:list}
代码解析:
- 我们将
cn_substr的结果赋值给一个变量$description。 - 使用
strlen()比较截取后的字符串长度和原始字符串的长度。 - 如果截取后的长度小于原始长度,说明被截断了,就在
$description后面拼接上 。 echo出最终结果。
页 (article_*.php) 截取文章内容作为描述
文章可能没有填写 description 字段,或者我们希望用文章的前几段内容作为描述,这时,我们可以截取文章内容 (body)。
原始代码可能长这样:
{dede:field.body/}
修改后,截取文章内容作为描述: 假设我们想用文章的前 200 个字符作为描述。
<p>
[field:body function='cn_substr(html2text(@me), 200)'/]
</p>
代码解析:
[field:body ...]: 调用文章内容字段。html2text(@me): 这是一个非常实用的函数,html2text会把 HTML 标签(如<p>,<div>,<img>等)全部去除,只保留纯文本内容。强烈建议在截取body时使用它,否则会截取到一堆无意义的 HTML 代码。cn_substr(..., 200): 再对纯文本内容进行截取。
同样,可以加上省略号:
<p>
[field:body function='
$content = cn_substr(html2text(@me), 200);
if(strlen(cn_substr(html2text(@me), 200)) < strlen(html2text(@me))) {
$content .= "...";
}
echo $content;
'/]
</p>
在首页 (index.htm) 或频道页截取
首页和频道页通常也包含文章列表,其截取方法和列表页完全一样,只需要将 {dede:list} 标签换成 {dede:arclist} 即可。
在 {dede:arclist} 中使用:
{dede:arclist titlelen='30' row='5'}
<li>
<a href="[field:arcurl/]">[field:title/]</a>
<p>[field:description function='cn_substr(@me, 50)'/]</p>
</li>
{/dede:arclist}
{dede:arclist} 的用法和 {dede:list} 几乎一致,只是 arclist 更灵活,可以在一个页面上调用多个栏目的文章。
总结与最佳实践
- 核心函数:
cn_substr()是处理中文字符串截取的利器。 @me变量:在function属性中,@me代表当前标签的原始值,是连接模板和 PHP 函数的桥梁。- 截取
body:如果要截取文章内容,务必先用html2text()函数去除 HTML 标签,否则结果会很混乱。 - 添加省略号:为了更好的用户体验,截取后最好判断一下是否被截断,并加上 。
- 性能考虑:
html2text()和strlen()等函数会增加服务器计算量,如果网站文章量巨大且访问量高,建议在后台手动填写description字段,而不是在前端动态生成,动态生成适合对 SEO 要求不高,但追求内容展示灵活性的场景。
希望这份详细的讲解能帮助你完全掌握 DedeCMS 中 description 的截取方法!
