TanzCMS开源CMS系统

模板标签开发手册

模板标签处理器、参数、缓存、标签生成器声明和安全性能要求。

更新:2026-05-31 02:42:50 浏览:4

模板标签开发手册

模板标签用于把结构化数据交给主题模板,不用于输出整块固定页面。新增标签应优先返回数据、URL、状态和链接数组,HTML 输出只作为兼容或低层组件能力。

标签类型

类型 示例 说明
数据标签 {content}{category}{search} 读取数据并建立循环上下文
URL 标签 {category_url}{member_url} 生成页面地址
资源标签 {theme_asset}{plugin_asset} 生成资源地址
业务标签 {member_order} 由模块或插件提供业务状态
兼容 HTML 标签 {thumb_img}{file_link} 输出小片段 HTML

处理器接口

运行时标签处理器实现:

use App\Cms\Templates\Contracts\TemplateTagHandlerContract;
use App\Cms\Templates\TemplateRenderContext;

class FriendLinksTag implements TemplateTagHandlerContract
{
    public function names(): array
    {
        return ['friend_links'];
    }

    public function render(string $name, array $attributes, string $body, TemplateRenderContext $context): string
    {
        // 读取参数、查询服务、渲染循环体
    }
}

注册:

app(TemplateTagRegistry::class)->register(app(FriendLinksTag::class));

参数规则

标签参数必须转换为声明式条件:

{content model=article catid=$category.id num=10 order=new return=t}

处理器需要校验:

  • 模型、栏目、字段是否存在。
  • 排序值是否在允许列表中。
  • 数量和分页是否超过上限。
  • 字段条件是否属于可查询字段。
  • 当前会员态、游客态是否允许读取。

不得让模板传入 SQL 片段、任意表名、任意字段表达式或未受控 join。

循环变量

官方示例约定:

场景 默认变量
内容列表 $t
栏目列表 $t 或自定义 return=c
搜索结果 $rs
详情页 $title$content$fields.xxx.text

新增标签应支持 return 参数,避免多个标签嵌套时变量冲突。

空数据分支

数据标签应支持 {empty}

{friend_links group=home return=link}
  <a href="{$link.url}">{$link.title}</a>
{empty}
  <span>暂无链接</span>
{/empty}
{/friend_links}

缓存与性能

标签处理器需要考虑:

  • 游客态和会员态缓存不同。
  • 模型、栏目、字段、主题和插件变化后缓存失效。
  • 循环中嵌套标签容易产生 N+1 查询,应批量取数。
  • 列表标签必须限制 numpagesize 和危险排序。
  • 慢标签应记录来源、参数和耗时,便于排查。

标签生成器声明

模块或插件可以在 manifest 中声明 template_tags,供标签生成器展示:

{
  "template_tags": [
    {
      "value": "friend_links",
      "label": "友情链接",
      "snippet": "{friend_links group={{group}} return={{return}}}...{/friend_links}",
      "defaults": {
        "group": "home",
        "return": "link"
      }
    }
  ]
}

template_tags 只声明生成器展示项,不注册运行时处理器。真正的标签仍由 ServiceProvider 注册。

安全输出

  • 普通变量默认安全转义。
  • 富文本、已清洗 HTML 或系统低层渲染器输出才允许 {html ...}
  • 插件返回的内容默认当作用户输入处理。
  • 标签处理器不得把未经清洗的请求参数拼入 HTML、SQL 或文件路径。