Scriban 是一个面向 .NET 平台的脚本语言与文本模板引擎,由 Alexandre Mutel(网名 xoofx)开发,主要用途是文本模板渲染,并提供了兼容 Liquid 模板语法的解析模式。它以自定义词法分析器和语法分析器生成完整抽象语法树为基础,解析与渲染过程注重低内存分配,同时通过默认不暴露 .NET 对象的运行模型来控制模板可访问的范围。该引擎以 NuGet 包形式发布,遵循 BSD-2-Clause 许可。
定义
Scriban 是一个为 .NET 平台设计的脚本语言与文本模板引擎,以文本模板渲染为主要用途,同时带有解析 Liquid 模板的兼容模式[1][2]。模板文本与代码块混排,代码块写在 {{ 与 }} 之间,解析后通过 Template.Render 方法结合数据模型输出字符串[3]。
除模板场景外,Scriban 也可以在不使用 {{ }} 包裹的纯脚本模式下运行,用于构建面向特定领域的小型脚本语言[4]。项目中同时提供 Scriban.Signed 包,用于需要签名程序集的场景,以及从 3.2.1 版本开始提供的源码内嵌方式[5]。
原理
引擎使用自行实现的词法分析器与语法分析器,把模板编译为完整的抽象语法树(AST),而不是依赖正则表达式进行匹配,因此解析速度较快、运行时内存分配较少[4]。解析结果由 Template 对象的 Page 属性承载,解析过程中的错误与警告记录在 Messages 属性中,可通过 HasErrors 判断[6]。
渲染由 TemplateContext 承担,它保存变量与函数的栈、输出缓冲区,并缓存 include 指令加载过的模板。模板可访问的变量与函数通过 ScriptObject 提供,该类型是字典的扩展实现,可以导入 .NET 委托、静态方法或对象实例[6]。默认情况下,.NET 对象的属性与方法会以小写加下划线的形式暴露,例如 MyMethodIsNice 对应 my_method_is_nice,这一约定最初是为了与 Liquid 保持一致,可通过 MemberRenamer 修改[4]。
语言层面支持变量、表达式、条件、循环、函数、管道、对象与数组等构造[1]。函数以管道符串联,例如 {{ "hello world" | string.capitalize }};内置函数覆盖字符串、数组、日期、数学、正则、html 等类别[3][5]。
运行时模型默认不暴露任何未经显式允许的 .NET 对象,属于沙箱式设计的组成部分;模板上下文还可以对循环次数、递归深度、字符串与输出增长、正则执行时间设置上限,例如新上下文默认循环上限为 1000、递归上限为 100、字符串物化上限为 1048576 个字符、正则超时为 10 秒[7]。官方文档同时说明,这并非围绕任意 .NET 对象的进程级沙箱或安全边界,若宿主暴露了可访问文件系统、网络或密钥的对象,模板即可使用这些能力,因此不可信模板需要宿主自行限制暴露面[7]。
发展历程
Scriban 由 Alexandre Mutel(网名 xoofx)创作。NuGet 上的 0.1.0 版本于 2016 年 5 月 31 日发布,此后持续迭代,版本号陆续推进到 3.x、5.x、6.x 与 7.x 系列[8][2][9]。
早期版本定位为文本模板语言与引擎,兼容 .NET Framework 4.6、UWP 10 与 CoreCLR 等框架配置,并说明自身与 Liquid、Handlebars 相近而额外支持管道、多行语句、func 语句声明的自定义函数以及类 JSON 的对象与数组写法。
3.0 版本是变化较大的一次更新:目标框架改为 .NET Standard 2.0 及以上,抽象语法树可通过 ScriptVisitor 完整遍历并支持访问父节点,新增十六进制与二进制数字、大整数、参数化函数与内联函数、可选成员访问 ?.、条件表达式,并把语言模式与解析模式拆分为 ScriptLang 与 ScriptMode,在 Scriban 与 Liquid 之外增加了 Scientific 解析模式[4]。
较新的版本面向 .NET 8 及以上提供了对原生 AOT 与裁剪友好的 API,基于 ScriptObject 的接口在原生 AOT 发布时不产生链接器警告[5]。软件以 BSD-2-Clause 许可发布[2]。
应用
Scriban 的典型用途是依据模板和数据模型动态生成文本内容。在 .NET 生态中,它被用作其他库的模板渲染后端,例如 ABP 框架的文本模板模块包含基于 Scriban 的实现,Axuno.TextTemplating 即从其中的轻量部分衍生而来。
静态站点生成框架 Statiq、生成电子邮件正文的多个 NuGet 包、以及把 MTConnect 标准模型转译为其他格式的工具,都提供了基于 Scriban 的渲染支持[10]。Unity 也发布过对应的包管理器版本,用于在 Unity 项目中使用该模板语言[11]。
除模板渲染外,Scriban 也能作为通用脚本引擎嵌入,例如面向开发者的命令行计算器 kalk 的脚本引擎即以其为核心[12][13]。Textrude 等工具则用 Scriban 模板把 CSV、JSON、YAML 数据转换为代码,Visual Studio Code 上还有提供语法着色的扩展[4]。
局限
Scriban 的运行模型虽然默认不暴露未授权的 .NET 对象,但官方明确表示它并不构成进程级沙箱或针对任意 .NET 对象的安全边界;如果宿主暴露了具备文件系统、网络或敏感状态访问能力的对象,或配置了从磁盘读取的模板加载器,模板就能使用这些能力[7]。
Liquid 语言本身没有被严格统一的定义,存在多种语法版本,因此用 Scriban 解析 Liquid 模板时存在若干限制[4]。此外,Scriban 不支持函数重载,从同一类型导入的函数必须使用互不相同的名称[6]。
在目标框架上,3.0 版本起仅支持 .NET Standard 2.0 及以上,对 .NET 3.5、4.0、4.5 以及 .NET Standard 1.1、1.3 的支持只保留在已不再维护的 2.x 版本中[4]。TemplateContext 也不是线程安全的,同一实例不宜跨线程共享[6]。源码内嵌模式下所有 Scriban 类型被标记为 internal,源文件在当前版本中未设为只读,修改会影响同一台机器上使用内嵌源码的其他项目[5]。
在使用 Liquid 兼容模式时,Scriban 会将 Liquid 模板翻译为自身的运行时抽象语法树,因而其行为受自身运行时语义约束,语法映射的细节以官方 Liquid 支持文档为准[6]。
参见
参考资料
- Scriban [引用日期2026-10-14]
- scriban - NuGetarrow_drop_down [引用日期2026-10-14]
- Getting started | Scriban [引用日期2026-10-14]
- scriban [引用日期2026-10-14]
- Scriban 7.0.1 [引用日期2026-10-14]
- Runtime [引用日期2026-10-14]
- Safe runtime | Scriban [引用日期2026-10-14]
- Scriban 0.1.0 - NuGet Package for .NET | NuBrowse [引用日期2026-10-14]
- Scriban 7.0.5 NuGet Package [引用日期2026-10-14]
- packages [引用日期2026-10-14]
- com.unity.nuget.scriban | Scriban | 2.1.4-preview [引用日期2026-10-14]
- socket.dev 上的网页 [引用日期2026-10-14]
- Scriban on NuGet [引用日期2026-10-14]