- 开发工具
- CLI
- 配置管理
【免费下载链接】chezmoi
Manage your dotfiles across multiple diverse machines, securely.
toPrettyJson是 chezmoi 模板体系中用于生成“美化排版 JSON”的核心函数:它把任意模板值序列化为带缩进的 JSON 字符串,并允许调用者自定义缩进字符串。本文以 官方参考文档 为骨架,结合 templatefuncs.go 的实现与 templatefuncs.txtar 的测试用例,讲解参数语义、源码原理、与toJson的差异以及三种实战用法,读完即可在 dotfiles 模板中熟练输出可读 JSON。
函数签名与参数语义
toPrettyJson的调用形式为:
toPrettyJson [indent] valuevalue:任意模板值(map、list、字符串、数字等),将被序列化为 JSON。indent(可选):嵌套元素相对父级的缩进字符串。默认值为两个空格(" ")。
原文档给出的最小示例:
{{ dict "a" (dict "b" "c") | toPrettyJson "\t" }}该表达式先用dict构造嵌套字典{"a": {"b": "c"}},再通过管道交给toPrettyJson "\t",输出结果约为:
{ "a": { "b": "c" } }由于indent是任意字符串,你可以传入"\t"(制表符)、" "(四个空格)甚至" "以外的任意组合,灵活适配不同团队或工具的缩进规范。
源码实现:默认缩进与参数校验
在 internal/cmd/templatefuncs.go 中,Config.toPrettyJsonTemplateFunc完整展现了该函数的底层逻辑:
func (c *Config) toPrettyJsonTemplateFunc(args ...any) string { //nolint:revive,staticcheck var ( indent = " " value any ) switch len(args) { case 1: value = args[0] case 2: var ok bool indent, ok = args[0].(string) if !ok { panic(fmt.Errorf("arg 1: expected a string, got a %T", args[0])) } value = args[1] default: panic(fmt.Errorf("expected 1 or 2 arguments, got %d", len(args))) } var builder strings.Builder encoder := json.NewEncoder(&builder) encoder.SetEscapeHTML(false) encoder.SetIndent("", indent) must(encoder.Encode(value)) return builder.String() }从中可以提炼出几条可验证的实现事实:
- 参数个数:严格接受 1 个(仅
value)或 2 个(indent, value)参数,其余数量会触发 panic,提示expected 1 or 2 arguments。 - 参数类型:第一个参数必须是
string,否则 panic 并报出实际类型(arg 1: expected a string, got a %T)。 - 默认缩进:
indent变量初始化为" "(两个空格),与文档声明完全一致。 - 输出实现:基于标准库
encoding/json的Encoder,通过SetIndent("", indent)实现美化排版,SetEscapeHTML(false)关闭 HTML 字符转义,最终以strings.Builder收集输出。
该函数在 internal/cmd/config.go 中被加入白名单,并在 internal/cmd/config.go 注册为模板函数"toPrettyJson": c.toPrettyJsonTemplateFunc,因此它在所有 chezmoi 模板(包括普通.tmpl文件与execute-template命令)中开箱即用。
与toJson的关键区别:HTML 字符不转义
toPrettyJson与toJson最值得注意的行为差异是HTML 转义。源码中显式调用了encoder.SetEscapeHTML(false),这意味着&、<、>等字符会原样输出,而不是被编码为\u0026、\u003c、\u003e。
这一点由 internal/cmd/testdata/scripts/templatefuncs.txtar 中的回归测试直接锁定:
# test that the toPrettyJson template function does not escape HTML characters, ... exec chezmoi execute-template '{{ dict "a" (dict "b" "&") | toPrettyJson " " }}' cmp stdout golden/toPrettyJson其期望输出(同文件 L336-L341):
{ "a": { "b": "&" } }作为对照,chezmoi 在设置formatIndent时会对toJson进行覆盖实现,见 internal/chezmoi/template.go,该实现并未关闭 HTML 转义。因此当模板数据包含 URL 中的&、HTML 标签字符时,toPrettyJson输出的内容更“原始”、更接近直接手写的 JSON,尤其适合生成需要被其他程序(如 jq、curl、配置文件解析器)再次读取的中间数据。
实战一:在execute-template中调试与生成 JSON
execute-template是验证和生成模板输出的标准入口。例如:
chezmoi execute-template '{{ dict "name" "chezmoi" "version" "2" | toPrettyJson }}'输出(默认两空格缩进):
{ "name": "chezmoi", "version": "2" }如需指定缩进,将indent作为第一个参数传入:
chezmoi execute-template '{{ dict "a" (dict "b" 1) | toPrettyJson "\t" }}'实战二:modify-template 中“读改写” JSON 文件
toPrettyJson最常见的生产用途是与fromJson、setValueAtPath配合,在modify-template脚本里对既有 JSON 文件做定点修改。官方在 manage-different-types-of-file.md 中给出的模板为:
{{- /* chezmoi:modify-template */ -}} {{ fromJson .chezmoi.stdin | setValueAtPath "key.nestedKey" "value" | toPrettyJson }}执行流程是:fromJson解析 stdin 中的原始 JSON →setValueAtPath设置嵌套路径的值 →toPrettyJson把修改后的结构重新输出为排版整齐的 JSON。由于toPrettyJson不会转义 HTML 字符,原文件中的&等字符在重写后得以原样保留,避免“读一次就变一次”的意外内容漂移。需要特别注意的是,modify-template 文件不能带.tmpl扩展名,否则不会被识别为修改模板。
配套函数矩阵
toPrettyJson并非孤立存在,它属于 chezmoi 的“编码/解码”函数家族,全部注册在 internal/cmd/config.go,并在 mkdocs.yml 中收录:
| 方向 | 函数 | 说明 |
|---|---|---|
| 解码 | fromJson/fromJsonc | JSON / JSONC 字符串 → 模板值 |
| 解码 | fromToml | TOML 字符串 → 模板值 |
| 解码 | fromYaml | YAML 字符串 → 模板值 |
| 编码 | toJson | 值 → 紧凑 JSON |
| 编码 | toPrettyJson | 值 → 美化缩进 JSON(不转义 HTML) |
| 编码 | toToml | 值 → TOML |
| 编码 | toYaml | 值 → YAML |
| 编码 | toIni | map → INI 格式 |
由此可以组合出多种转换管线,例如从 YAML 读取配置、改写后再以 JSON 输出:fromYaml ... | toPrettyJson。无论哪种组合,toPrettyJson都承担着“最终交付可读 JSON”的收尾角色。
使用注意事项
- 仅接受 1~2 个参数:多传或少传都会触发 panic,模板渲染直接失败,参数顺序必须是
indent在前、value在后。 indent必须是字符串:传入非字符串类型(如数字)会以 panic 终止并提示期望类型。- 输出以换行结尾:底层
json.Encoder.Encode会在 JSON 末尾追加一个换行符,若需嵌入其他模板上下文可配合trim使用。 - 文档参考:完整定义见 toPrettyJson.md;如希望了解
fromJson等反向解析函数的细节,可继续阅读同目录下的 fromJson.md、fromYaml.md 与 fromToml.md。
掌握toPrettyJson之后,你便能在 dotfiles 模板中随时生成结构清晰、可直接被下游工具消费的 JSON 输出——无论是调试数据、生成配置文件,还是对 JSON 类 dotfile 做无损的定点修改。
- 开发工具
- CLI
- 配置管理
【免费下载链接】chezmoi
Manage your dotfiles across multiple diverse machines, securely.
相关推荐
chezmoi 模板函数 `hexEncode` 与 `hexDecode`:十六进制编码与解码实战指南
chezmoi 模板函数 hexEncode 与 hexDecode :十六进制编码与解码实战指南 hexEncode 与 hexDecode 是 chezmo
开发工具CLI配置管理chezmoi 模板函数 hexDecode 完全指南:在 dotfiles 模板中解码十六进制字符串
chezmoi 模板函数 hexDecode 完全指南:在 dotfiles 模板中解码十六进制字符串 hexDecode 是 chezmoi 模板系统提供的一
开发工具CLI配置管理chezmoi 模板函数 dashlanePassword:从 Dashlane 安全取回结构化密码数据
chezmoi 模板函数 dashlanePassword:从 Dashlane 安全取回结构化密码数据 导读 dashlanePassword 是 chezm
开发工具CLI配置管理
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考