DouPHP模板语法概述

发布时间:2013-11-16点击次数:14765

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}

注意事项

  1. 所有模板标签必须正确闭合
  2. 变量名区分大小写
  3. 修饰器参数使用冒号分隔
  4. 支持嵌套使用控制结构
  5. 模板文件通常以 .tpl为扩展名
  6. 避免在模板中编写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>