关闭转义 Nofilter
nofilter 是一个「裸词标志」,追加在输出末尾,用于对这一处输出关闭全局自动 HTML 转义,让内容原样输出。
一、语法
nofilter 直接写在标签内、变量或表达式之后,不带等号、不带引号:
{$article.content nofilter}
{$user ? $a : $b nofilter}
{url link='search' nofilter}
二、语义与判定关系
全局自动转义由引擎开关 escapeHtml 控制。开启后,{$var} 默认会被 htmlspecialchars 转义;此时三者的关系如下:
| 情形 | 是否转义 |
|---|---|
escapeHtml 关闭(DouPHP 前台默认) |
本就不转义,nofilter 无实际差别 |
escapeHtml 开启,输出未带 nofilter、未带 |escape |
自动转义 |
escapeHtml 开启,输出带 nofilter |
不转义,原样输出 |
escapeHtml 开启,修饰器链已含 |escape |
按 |escape 转义一次,不再重复追加全局转义 |
也就是说:nofilter 与 |escape 是两个方向相反的手段——nofilter 关闭转义、|escape 主动转义;两者都能让引擎跳过「再补一次全局转义」,避免双重转义。
三、典型用法:输出富文本 HTML
DouPHP 前台的内容渲染器(MarkdownRenderer)会把正文 Markdown 转成 HTML 再注入模板变量。此时模板必须用 nofilter 输出,否则 HTML 标签会被转义成可见的实体文本:
{* 正确:原样输出渲染好的 HTML 正文 *}
<div class="content">{$article.content nofilter}</div>
{* 错误(开启转义时):整段 HTML 被转义成 <p> 之类的可见文本 *}
<div class="content">{$article.content}</div>
四、{url} 同样支持
{url} 标签也接受 nofilter,且支持裸词与属性两种写法:
{url link='search' nofilter}
{url link='search' nofilter=true}
开启全局转义且未加 nofilter 时,{url} 的结果会被 htmlspecialchars;加 nofilter 则原样输出。详见「路由链接 Url」篇。
五、安全提醒
nofilter 意味着「我信任这段内容、放弃转义」。只应对已由可信渲染器产出的 HTML(如内容正文)使用;对任何来自用户输入、未经净化的数据,切勿用 nofilter 直出,否则会造成 XSS。用户内容的正确姿势是默认转义,或先经 |escape 处理。