模板里能调用哪些函数?为什么 ColumnsTree 用不了?

最后更新时间:2026-09-22 18:55:51

1. 结论:只能用白名单里的 47 个

VVCMS 在模板层暴露的函数是显式白名单,不是把项目里所有函数都开放给模板。当前共 47 个,分两类:

  • 基础函数 22 个:判断、兜底、时间、路径、字符串处理,例如 HasPrefixdefaultdateurlassetStrSubSplitprintfsafeHTML
  • 系统定制函数 25 个:直接消费内容、栏目和主题配置,例如 SiteColumnColumnContentsContentByIDTagsRelatedMessagesReverse

完整清单见文档栏目下的基础函数系统定制函数两篇。

2. 为什么 ColumnsTree 不能用了

ColumnsTree 曾用于读取全站栏目树,现已从白名单中移除,原因是安全收敛:把完整栏目结构直接暴露给模板层,会让模板作者(不一定是站点管理员)有能力输出本不该对外展示的栏目,例如未启用、隐藏或内部使用的栏目。

这不是遗漏,是刻意为之——项目里有专门的单元测试断言它不得出现在模板函数表中。

替代方案

按需组合下面几个函数,只取真正要展示的部分:

  • ChildrenColumns 传父栏目 slug —— 取某个栏目的直接子栏目
  • ParentColumn 传栏目 ID —— 取父栏目,常用于面包屑
  • SiblingColumns 传栏目 ID —— 取同级栏目
  • Column 传 slug、或 ColumnByID 传 ID —— 取单个栏目

这样既拿到了导航结构,又不会把整棵内部栏目树泄漏出去。

3. 白名单是强制校验的

函数表由 themeTemplateFuncs() 注册,并有单元测试强制校验名称与总数。这意味着:

  • 私自往函数表里加一个而不同步更新白名单,测试会直接失败;删掉一个也一样。
  • 这条约束保证了「文档上写的」和「模板里能用的」始终一致,不会出现文档写了却调不到的情况。

4. 我需要一个新函数,怎么办

模板层不支持运行时注册自定义函数,必须改代码。完整路径是同步改三处

  1. server/gin.go 中的 themeTemplateFuncs() 增加函数实现
  2. server/gin_test.goTestThemeTemplateFuncNames 的白名单补上名称(总数会变,测试会校验)
  3. 文档栏目下的函数清单同步补一行

三处缺一处,要么测试过不去,要么文档与实际对不上。

5. 常见误用

  • 想在模板里直接查数据库:不支持,也不应该支持。需要新数据就按第 4 节加函数。
  • 用了没在白名单里的函数:项目定制函数一律以白名单为准,不要想当然。
  • 依赖文档里没列的函数:既然有强制校验,文档没列的基本就是没有,先查清单再动手。