` ``` {$变量|nl2br} ``` ### 4. strip_tags — 去除 HTML 标签 ``` {$变量|strip_tags:是否替换为空格} ``` - 是否替换为空格:`true` 替换为空格(默认),`false` 直接删除 ``` {$html_content|strip_tags} {$html_content|strip_tags:false} ``` ### 5. capitalize — 首字母大写 ``` {$变量|capitalize:是否数字大写} ``` - 是否数字大写:`true` 数字开头的词也大写(默认 `false`) ``` {$title|capitalize} ``` ### 6. cat — 字符串连接 ``` {$变量|cat:"连接字符串"} ``` ``` {$name|cat:"先生"} ``` ### 7. count_characters — 统计字符数 ``` {$变量|count_characters:是否包含空格} ``` - 是否包含空格:`true` 含空格(默认 `false`) ### 8. count_paragraphs — 统计段落数 ``` {$变量|count_paragraphs} ``` ### 9. count_sentences — 统计句子数 ``` {$变量|count_sentences} ``` ### 10. count_words — 统计单词数 ``` {$变量|count_words} ``` ### 11. date_format — 日期格式化 ``` {$日期变量|date_format:格式字符串:默认日期} ``` 使用 `strftime` 占位符(PHP 8.1+ 自动映射为 `date()` 等价格式): - `%Y` 四位年份 / `%y` 两位年份 - `%m` 月份(01-12)/ `%d` 日期(01-31)/ `%e` 日期(不补零) - `%H` 24 小时制 / `%I` 12 小时制 / `%M` 分钟 / `%S` 秒 - `%a` 星期缩写 / `%A` 星期全称 / `%b` 月份缩写 / `%B` 月份全称 - `%p` AM/PM / `%R` `H:i` / `%T` `H:i:s` ``` {$timestamp|date_format:"%Y-%m-%d %H:%M:%S"} {$create_time|date_format:"%Y年%m月%d日"} ``` 输入可为时间戳、`YYYYMMDDHHMMSS` 串或 `strtotime` 可解析字符串。 ### 12. default — 默认值 ``` {$变量|default:"默认值"} ``` 当变量未设置或为空字符串时回退默认值。 ### 13. indent — 每行缩进 ``` {$变量|indent:缩进数:缩进字符} ``` - 缩进数:每行缩进字符数(默认 4) - 缩进字符:默认空格 ``` {$code|indent:8:" "} ``` ### 14. string_format — sprintf 格式化 ``` {$变量|string_format:"格式"} ``` ``` {$price|string_format:"%.2f"} ``` ### 15. strip — 多空白压缩 ``` {$变量|strip:替换字符} ``` 把连续空白压缩为单个字符(默认空格)。 ### 16. lower — 转小写 ``` {$变量|lower} ``` ### 17. upper — 转大写 ``` {$变量|upper} ``` ### 18. replace — 字符串替换 ``` {$变量|replace:"查找字符串":"替换字符串"} ``` ``` {$content|replace:"旧文本":"新文本"} ``` ### 19. spacify — 字符间插入分隔 ``` {$变量|spacify:分隔字符} ``` ``` {$word|spacify:"-"} ``` ### 20. wordwrap — 自动换行 ``` {$变量|wordwrap:行长度:换行符:是否截断单词} ``` - 行长度:默认 80 - 换行符:默认 `\n` - 是否截断单词:`true` 在词中间换行(默认 `false`) ### 修饰器链式组合 ``` {$content|truncate:100|nl2br|strip_tags} {$title|escape:"html"|default:"默认标题"} ``` ## 控制结构 控制结构包含条件判断与循环。循环标签除通用的 `{foreach}` 外,还有 DouPHP 专属的 `{list}` / `{category}`——后两者自动从 Portal 取数后按与 `{foreach}` 相同的方式循环,共享 `item` / `key` / `name` / `offset` 参数、`@property` 循环属性、`{break}` / `{continue}` 与空态分支。 ### if 条件判断 ``` {if $条件} ... {elseif $其他条件} ... {else} ... {/if} ``` #### 比较与逻辑运算符 | 符号形式 | 等价词 | 含义 | | -------------- | ---------------- | -------- | | `==` | `eq` | 等于 | | `!=`、`<>` | `ne` / `neq` | 不等于 | | `===` | — | 全等于 | | `!==` | — | 不全等于 | | `>` | `gt` | 大于 | | `<` | `lt` | 小于 | | `>=` | `ge` / `gte` | 大于等于 | | `<=` | `le` / `lte` | 小于等于 | | `&&` | `and` | 与 | | `\|\|` | `or` | 或 | | `!` | `not` | 非 | | `%` | `mod` | 取模 | 同时支持位运算 `& | ^ ~ << >>` 和算术 `+ - * /`,并允许括号分组。 ``` {if $count > 0 && $user.logged_in} {if $status eq 1} {if ($a + $b) % 2 eq 0} ``` ### foreach 循环 ``` {foreach from=$数组变量 item=值变量 [key=键变量] [name=循环名称] [limit=数量] [offset=起始位置]} ... {foreachelse} 数组为空时显示 {/foreach} ``` #### 参数说明 | 参数 | 必需 | 说明 | | ---------- | ---- | ----------------------------------------------------------------- | | `from` | 是 | 待遍历的数组或对象 | | `item` | 是 | 当前元素的值变量名(字面标识符) | | `key` | 否 | 当前元素的键变量名 | | `name` | 否 | 循环名称(用于 `$douview.foreach.NAME.*` 访问;省略时自动生成) | | `limit` | 否 | 最多循环次数(取数后切片,类似 `array_slice`) | | `offset` | 否 | 跳过的元素数量(从 0 开始) | #### 循环属性(@property 语法,推荐) 无需声明 `name`,直接在 `item` 变量后用 `@` 前缀访问循环元数据: | 属性 | 说明 | 示例输出 | | -------------- | ------------------------- | ------------ | | `@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}【最新】{/if} {$article@iteration}. {$article.title} {if $article@last}(共{$article@total}篇){/if} {/foreach} ``` #### limit / offset 分页 ``` {* 只显示前 10 条 *} {foreach from=$news item=news limit=10}
{$product.name}
{/list}
```
> 同一请求内相同 `module + props` 的 `{list}` 块结果会被缓存,重复块不重复查询。
### — 分类树
仅栏目型模块(`module.column_module`)可用,输出分类嵌套树。支持两种模式:
#### 模式一:纯分类树
```
{category module="模块名" item=节点变量 [cur=当前分类ID] [key=键] [name=名称] [offset=跳过数]}
...
{categoryelse}
无分类时显示
{/category}
```
#### 模式二:分类树 + 每类内容
```
{category module="模块名" with="items" [perCat=每类条数] [children=是否含子节点]
[excerpt=截字长度] item=节点变量}
{* 节点结构:category_id / name / list(内容行数组)/ child(子节点数组或空) *}
...
{categoryelse}
无分类时显示
{/category}
```
#### 参数说明
| 参数 | 说明 |
| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| `module` | 模块名(字面标识符) |
| `with` | 仅接受字面量 `"items"`,启用「分类树 + 每类内容」模式 |
| `perCat` | 每个分类附带的内容条数(默认 5,仅 `with="items"` 时生效) |
| `children` | 是否递归挂载子节点(仅 `with="items"` 时生效) |
| `cur` | 当前激活分类 ID(仅纯树模式生效;引擎据此给 id 匹配的节点打 `cur=true` 标记,便于模板高亮当前分类。`with="items"` 模式忽略此参数) |
| `excerpt` | 内容行 `description` 截字长度(默认 200) |
| `item` / `key` / `name` / `offset` | 同 `{foreach}` |
```
{* 纯分类树:cur=$cat_id 让匹配节点带上 cur=true 标记,模板直接据此高亮 *}
{category module="article" cur=$cat_id item=cat}
{$cat.cat_name}
-
{foreach from=$cat.list item=row}
- {$row.title} {/foreach}
{$item.title}
{/foreach} ``` ## 内置标签 ### include — 包含子模板 ``` {include file="模板文件名" [变量1="值1" 变量2=$值2] [assign="变量名"]} ``` - `file`:要包含的模板资源名(必需) - `assign`:将包含结果赋值给指定变量而非直接输出(可选) - 其他属性:作为局部变量传递给子模板 ``` {include file="header.tpl" title=$page_title} {include file="inc/pager.tpl"} {include file="box.tpl" box=$box assign="box_html"} ``` > 模板文件扩展名白名单:`.tpl` / `.htm` / `.html` / `.dwt`。资源名禁止包含 `..` 或绝对路径,防止路径穿越。 ### — 生成路由 URL 把点分路由键编译为 `route()` 调用,是 DouPHP 模板生成链接的标准方式。 ``` {url link="路由键" [params=$数组] [page=$页码] [options=$选项] [nofilter] k1=$v1 k2=$v2 ...} ``` #### 保留属性 | 属性 | 说明 | | ------------ | ---------------------------------------------------------------- | | `link` | 点分路由键,如 `'article.show'`、`'admin.user.edit'`(必需) | | `params` | 路由参数数组(可选,与内联属性合并) | | `page` | 分页页码,并入 `options.page` | | `options` | 路由选项数组(如 `query`、`lang`) | | `nofilter` | 裸词标志,关闭自动 HTML 转义 | 除上述保留属性外,**其他内联属性自动并入 `params`**,作为路由参数。 ``` {* 基础用法 *} 文章 {* 带路径/查询参数 *} {$article.title} 编辑 {* 带分页 *} 订阅 {* 裸词参数值(非变量)*} 今日 ``` ### assign — 变量赋值 ``` {assign var="变量名" value="变量值"} ``` ``` {assign var="page_title" value="首页"} {assign var="user_level" value=$user.level} ``` ### strip — 压缩空白 ``` {strip}| 内容 |
- {$item.title}
{$title|capitalize}
{if $user.logged_in}欢迎回来,{$user.name|escape:"html"}!
{else}请先登录
{/if}文章列表
{list module="article" catId=$cat_id limit=10 item=article name=art}{$article@iteration}. {$article.title|truncate:50}
{$article.description|truncate:200|nl2br}
暂无文章
{/list}分类导航
-
{category module="article" cur=$cat_id item=cat}
- {$cat.cat_name} {categoryelse}
- 暂无分类 {/category}
