DouPHP Smarty 模板引擎使用文档
基本语法
模板变量输出
{$变量名}
示例:{$title}
注释
{* 这是注释内容 *}
保留分隔符
{ldelim} - 输出左分隔符 {
{rdelim} - 输出右分隔符 }
变量修饰器
修饰器用于对变量进行格式化处理,使用管道符 | 分隔。
1. truncate - 截断字符串
{$变量|truncate:长度:省略符:是否断词:是否中间截断}
参数说明:
- 长度:截断后的最大长度(默认80)
- 省略符:截断后显示的省略符号(默认...)
- 是否断词:false=不在单词中间截断,true=在单词中间截断(默认false)
- 是否中间截断:false=从末尾截断,true=从中间截断(默认false)
示例:
{$content|truncate:100}
{$content|truncate:50:"...更多":false}
2. escape - 转义输出
{$变量|escape:转义类型:字符集}
转义类型:
html- HTML转义(默认)htmlall- 所有HTML实体转义url- URL编码urlpathinfo- URL路径编码(保留斜杠)quotes- 转义单引号hex- 十六进制编码hexentity- 十六进制实体decentity- 十进制实体javascript- JavaScript转义mail- 邮箱地址保护显示nonstd- 非标准字符转义
示例:
{$user_input|escape:"html"}
{$url|escape:"url"}
3. nl2br - 换行符转换
{$变量|nl2br}
将换行符转换为 <br> 标签
4. strip_tags - 去除HTML标签
{$变量|strip_tags:是否替换为空格}
参数:
- 是否替换为空格:true=替换为空格,false=直接删除(默认true)
示例:
{$html_content|strip_tags}
{$html_content|strip_tags:false}
5. capitalize - 首字母大写
{$变量|capitalize:是否数字大写}
参数:
- 是否数字大写:true=数字也大写,false=数字不大写(默认false)
示例:
{$title|capitalize}
6. cat - 字符串连接
{$变量|cat:"连接字符串"}
示例:
{$name|cat:"先生"}
7. count_characters - 统计字符数
{$变量|count_characters:是否包含空格}
参数:
- 是否包含空格:true=包含空格,false=不包含空格(默认false)
8. count_paragraphs - 统计段落数
{$变量|count_paragraphs}
9. count_sentences - 统计句子数
{$变量|count_sentences}
10. count_words - 统计单词数
{$变量|count_words}
11. date_format - 日期格式化
{$日期变量|date_format:格式字符串:默认日期}
格式字符串使用strftime格式:
%Y- 四位年份%y- 两位年份%m- 月份(01-12)%d- 日期(01-31)%H- 24小时制小时%I- 12小时制小时%M- 分钟%S- 秒%a- 星期缩写%A- 星期全称%b- 月份缩写%B- 月份全称
示例:
{$timestamp|date_format:"%Y-%m-%d %H:%M:%S"}
{$create_time|date_format:"%Y年%m月%d日"}
12. default - 默认值
{$变量|default:"默认值"}
当变量为空时显示默认值
13. indent - 缩进
{$变量|indent:缩进数:缩进字符}
参数:
- 缩进数:每行缩进的字符数(默认4)
- 缩进字符:使用的缩进字符(默认空格)
示例:
{$code|indent:8:" "}
14. lower - 转换为小写
{$变量|lower}
15. regex_replace - 正则替换
{$变量|regex_replace:正则表达式:替换内容}
示例:
{$phone|regex_replace:"/(\d{3})\d{4}(\d{4})/":"$1****$2"}
16. replace - 字符串替换
{$变量|replace:"查找字符串":"替换字符串"}
示例:
{$content|replace:"旧文本":"新文本"}
17. spacify - 字符间插入空格
{$变量|spacify:分隔字符}
参数:
- 分隔字符:插入的字符(默认空格)
示例:
{$word|spacify:"-"}
18. string_format - 格式化字符串
{$变量|string_format:"格式"}
使用sprintf格式
示例:
{$price|string_format:"%.2f"}
19. strip - 去除多余空格
{$变量|strip:替换字符}
参数:
- 替换字符:替换多个空格的字符(默认空格)
20. upper - 转换为大写
{$变量|upper}
21. wordwrap - 自动换行
{$变量|wordwrap:行长度:换行符:是否截断单词}
参数:
- 行长度:每行最大长度(默认80)
- 换行符:使用的换行字符(默认\n)
- 是否截断单词:true=在单词中间换行,false=不在单词中间换行(默认false)
修饰器组合使用
可以连续使用多个修饰器:
{$content|truncate:100|nl2br|strip_tags}
控制结构
if条件判断
{if $条件}
...
{elseif $其他条件}
...
{else}
...
{/if}
条件运算符:
==,eq- 等于!=,ne,neq- 不等于>,gt- 大于<,lt- 小于>=,ge,gte- 大于等于<=,le,lte- 小于等于===- 全等于!==- 不全等于&&,and- 与||,or- 或!,not- 非%,mod- 取模
is表达式(特殊判断)
{if $变量 is even}...{/if} // 是否为偶数
{if $变量 is odd}...{/if} // 是否为奇数
{if $变量 is even by $除数}...{/if} // 除以某数后是否为偶数
{if $变量 is odd by $除数}...{/if} // 除以某数后是否为奇数
{if $变量 is div by $除数}...{/if} // 是否能被某数整除
示例:
{if $count is even}偶数{/if}
{if $number is div by 3}能被3整除{/if}
section循环(数值索引数组)
{section name=循环名称 loop=$数组变量}
索引:{$smarty.section.循环名称.index}
序号:{$smarty.section.循环名称.iteration}
总数:{$smarty.section.循环名称.total}
当前值:{$数组变量[循环名称]}
是否为第一个:{$smarty.section.循环名称.first}
是否为最后一个:{$smarty.section.循环名称.last}
{sectionelse}
数组为空时显示
{/section}
参数:
name- 循环名称(必需)loop- 数组变量或数值(必需)start- 起始索引(默认0或根据step决定)step- 步长(默认1)max- 最大循环次数show- 是否显示(默认true)
示例:
{section name=i loop=$list start=0 step=1}
<li>第{$smarty.section.i.iteration}项:{$list[i]}</li>
{/section}
foreach循环(关联数组或对象)
{foreach from=$数组变量 item=值变量 key=键变量 name=循环名称}
键:{$键变量}
值:{$值变量}
索引:{$smarty.foreach.循环名称.index}
序号:{$smarty.foreach.循环名称.iteration}
总数:{$smarty.foreach.循环名称.total}
是否为第一个:{$smarty.foreach.循环名称.first}
是否为最后一个:{$smarty.foreach.循环名称.last}
{foreachelse}
数组为空时显示
{/foreach}
参数:
from- 数组或对象变量(必需)item- 值变量名(必需)key- 键变量名(可选)name- 循环名称(可选)
Smarty 3 增强语法
1. @属性支持(无需声明 name)
从 Smarty 3 开始,可以在 item 变量后直接使用 @ 前缀访问循环属性,无需显式声明 name:
{foreach from=$数组变量 item=值变量}
序号(从1开始):{$值变量@iteration}
索引(从0开始):{$值变量@index}
总数:{$值变量@total}
是否为第一个:{$值变量@first}
是否为最后一个:{$值变量@last}
是否有数据:{$值变量@show}
{/foreach}
| @属性 | 说明 | 示例输出 |
|---|---|---|
@iteration |
当前迭代序号(从1开始) | 1, 2, 3... |
@index |
当前索引(从0开始) | 0, 1, 2... |
@total |
循环总数 | 5 |
@first |
是否为第一个元素 | true/false |
@last |
是否为最后一个元素 | true/false |
@show |
循环是否有数据 | true/false |
示例:
{foreach from=$articles item=article}
{if $article@first}<strong>【最新】{/if}
{$article@iteration}. {$article.title}
{if $article@last}<em>(共{$article@total}篇){/if}
{/foreach}
2. limit 和 offset 参数
用于限制循环次数和跳过部分元素(类似于数据库的 LIMIT 和 OFFSET):
{foreach from=$数组变量 item=值变量 limit=数量 offset=起始位置}
...
{/foreach}
| 参数 | 说明 |
|---|---|
limit |
最多循环的次数 |
offset |
跳过的元素数量(从0开始) |
示例:
{* 只显示前10条 *}
{foreach from=$news item=news limit=10}
<li>{$news.title}</li>
{/foreach}
{* 跳过前5条,显示接下来的10条 *}
{foreach from=$news item=news limit=10 offset=5}
<li>{$news.title}</li>
{/foreach}
{* 分页显示:第一页 *}
{foreach from=$products item=product limit=12}
<div class="product">{$product.name}</div>
{/foreach}
3. {break} 和 {continue} 控制标签
在循环中控制流程:
| 标签 | 说明 |
|---|---|
{break} |
立即跳出循环 |
{continue} |
跳过当前迭代,继续下一次循环 |
示例:
{foreach from=$list item=item}
{if $item.status eq 0}
{continue} {* 跳过未发布的文章 *}
{/if}
<p>{$item.title}</p>
{/foreach}
{foreach from=$list item=item}
{if $item@iteration > 10}
{break} {* 只显示前10条 *}
{/if}
<p>{$item.title}</p>
{/foreach}
4. 组合使用示例
{foreach from=$articles item=article limit=5}
<div class="article-item{if $article@first} first{/if}{if $article@last} last{/if}">
<span class="num">{$article@iteration}/{$article@total}</span>
<h3>{$article.title}</h3>
</div>
{/foreach}
5. 兼容性说明
{foreach from=$users item=user name=foo}+{$smarty.foreach.foo.iteration}:✅ 原有语法完全支持{foreach from=$users item=user}+{$user@iteration}:✅ 新增 Smarty 3 语法- 两种语法可以混合使用
示例:
{* 混用示例 *}
{foreach from=$users item=user name=user_list}
<tr>
<td>{$user@iteration}/{$user@total}</td>
<td>{$user.name}</td>
<td>{$smarty.foreach.user_list.first ? '管理员' : '普通用户'}</td>
</tr>
{/foreach}
完整示例
{foreach from=$articles item=article}
<div class="article">
<h3>
{if $article@first}[最新]{/if}
{$article.title}
{if $article@last}[完]{/if}
</h3>
<p>{$article.content|truncate:200}</p>
<p class="meta">
{* 使用 limit 只显示前3条标签 *}
{foreach from=$article.tags item=tag limit=3}
<span class="tag">{$tag.name}</span>
{/foreach}
{* 跳过状态为0的评论 *}
{foreach from=$article.comments item=comment}
{if $comment.status eq 0}{continue}{/if}
<div class="comment">{$comment.content}</div>
{/foreach}
</p>
</div>
{foreachelse}
<p>暂无文章</p>
{/foreach}
内置变量
Smarty系统变量
{$smarty.now} // 当前时间戳
{$smarty.template} // 当前模板文件名
{$smarty.version} // Smarty版本号
{$smarty.ldelim} // 左分隔符
{$smarty.rdelim} // 右分隔符
foreach循环变量
原有语法(需声明 name)
{$smarty.foreach.循环名称.index} // 从0开始的索引
{$smarty.foreach.循环名称.iteration} // 从1开始的序号
{$smarty.foreach.循环名称.first} // 是否为第一个
{$smarty.foreach.循环名称.last} // 是否为最后一个
{$smarty.foreach.循环名称.total} // 循环总数
{$smarty.foreach.循环名称.show} // 是否显示(数组是否非空)
新语法(无需声明 name)
{$变量名@index} // 从0开始的索引
{$变量名@iteration} // 从1开始的序号
{$变量名@first} // 是否为第一个
{$变量名@last} // 是否为最后一个
{$变量名@total} // 循环总数
{$变量名@show} // 是否显示(数组是否非空)
内置变量
Smarty系统变量
{$smarty.now} // 当前时间戳
{$smarty.template} // 当前模板文件名
{$smarty.version} // Smarty版本号
{$smarty.ldelim} // 左分隔符
{$smarty.rdelim} // 右分隔符
foreach循环变量
{$smarty.foreach.循环名称.index} // 从0开始的索引
{$smarty.foreach.循环名称.iteration} // 从1开始的序号
{$smarty.foreach.循环名称.first} // 是否为第一个
{$smarty.foreach.循环名称.last} // 是否为最后一个
{$smarty.foreach.循环名称.total} // 循环总数
{$smarty.foreach.循环名称.show} // 是否显示(数组是否非空)
section循环变量
{$smarty.section.循环名称.index} // 当前索引
{$smarty.section.循环名称.index_prev} // 上一个索引
{$smarty.section.循环名称.index_next} // 下一个索引
{$smarty.section.循环名称.iteration} // 从1开始的序号
{$smarty.section.循环名称.first} // 是否为第一个
{$smarty.section.循环名称.last} // 是否为最后一个
{$smarty.section.循环名称.rownum} // 当前行号(同iteration)
{$smarty.section.循环名称.total} // 循环总数
{$smarty.section.循环名称.show} // 是否显示
包含文件
include指令
{include file="模板文件名" 变量1="值1" 变量2="值2"}
或
{include file="模板文件名" 变量1=$值1 变量2=$值2 assign="变量名"}
参数:
file- 包含的模板文件(必需)assign- 将包含内容赋值给变量(可选)- 其他参数:传递给包含模板的变量
示例:
{include file="header.tpl" title=$page_title}
{include file="footer.tpl"}
变量赋值
assign指令
{assign var="变量名" value="变量值"}
示例:
{assign var="page_title" value="首页"}
{assign var="user_level" value=$user.level}
strip标签
strip指令
去除HTML标签间的空白字符,压缩输出
{strip}
<table>
<tr>
<td>内容</td>
</tr>
</table>
{/strip}
注意事项
- 所有模板标签必须正确闭合
- 变量名区分大小写
- 修饰器参数使用冒号分隔
- 支持嵌套使用控制结构
- 模板文件通常以
.tpl为扩展名 - 避免在模板中编写PHP代码(出于安全考虑已禁用
{php}标签)
完整示例
<!DOCTYPE html>
<html>
<head>
<title>{$title|escape:"html"|default:"默认标题"}</title>
</head>
<body>
{include file="header.tpl"}
<h1>{$title|capitalize}</h1>
{if $user.logged_in}
<p>欢迎回来,{$user.name|escape:"html"}!</p>
{else}
<p>请先<a href="login.php">登录</a></p>
{/if}
<h2>文章列表</h2>
{foreach from=$articles item=article name=art}
<div class="article">
<h3>{$smarty.foreach.art.iteration}. {$article.title|truncate:50}</h3>
<p>{$article.content|truncate:200|nl2br}</p>
<p class="meta">
发布时间:{$article.publish_time|date_format:"%Y-%m-%d %H:%M"}
{if $article.comment_count > 0}
({$article.comment_count}条评论)
{/if}
</p>
</div>
{foreachelse}
<p>暂无文章</p>
{/foreach}
{include file="footer.tpl"}
</body>
</html> 