多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Hugo 中 resources.ExecuteAsTemplate:用 Go 模板动态生成资源的权威指南

Hugo 中 resources.ExecuteAsTemplate:用 Go 模板动态生成资源的权威指南 Hugo 中 resources.ExecuteAsTemplate用 Go 模板动态生成资源的权威指南【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugoresources.ExecuteAsTemplate是 Hugo 资源管道Hugo Pipes中的核心函数之一它允许你把一个 Resource 的内容当作 Go 模板解析并执行用站点配置、页面上下文等任意数据填充后生成并发布一份新的资源文件。本指南将完整讲解该函数的签名、底层实现原理、缓存行为并给出可直接复制的实战示例CSS 参数注入、管道链式加工、多语言场景帮助你掌握模板驱动资源生成这一常用模式。函数签名与基本行为根据 Hugo 官方函数文档 ExecuteAsTemplate.md该函数声明如下resources.ExecuteAsTemplate TARGETPATH CONTEXT RESOURCE返回值resource.Resource参数 1TARGETPATH字符串指定生成资源的目标发布路径相对于public目录。参数 2CONTEXT任意值作为模板执行时的数据上下文即模板里的.。参数 3RESOURCE一个 Resource 对象其内容将被当作 Go 模板源码读取。在模板命名空间层参数校验位于 resources.go函数要求必须恰好传入 3 个参数否则返回must provide targetPath, the template data context and a Resource object错误第三个参数必须实现resources.ResourceTransformer接口否则报type %T not supported in Resource transformations。函数将源资源的内容解析为 Go 模板后使用 targetPath 作为缓存键对结果进行缓存同一份模板、同一目标路径在重复渲染时不会重复执行模板解析。Hugo 会在你调用该资源对象的Publish、Permalink或RelPermalink方法时把资源发布到目标路径。底层实现原理函数在核心层的实现在 execute_as_template.go整个流程非常清晰func (t *executeAsTemplateTransform) Transform(ctx *resources.ResourceTransformationCtx) error { tplStr : helpers.ReaderToString(ctx.From) th : t.t.GetTemplateStore() ti, err : th.TextParse(ctx.InPath, tplStr) if err ! nil { return fmt.Errorf(failed to parse Resource %q as Template:: %w, ctx.InPath, err) } ctx.OutPath t.targetPath return th.ExecuteWithContext(ctx.Ctx, ti, ctx.To, t.data) } func (c *Client) ExecuteAsTemplate(ctx context.Context, res resources.ResourceTransformer, targetPath string, data any) (resource.Resource, error) { return res.TransformWithContext(ctx, executeAsTemplateTransform{ rs: c.rs, targetPath: paths.ToSlashTrimLeading(targetPath), t: c.t, data: data, }) }几个值得注意的实现细节转换键Transformation KeyexecuteAsTemplateTransform.Key()返回internal.NewResourceTransformationKey(execute-as-template, t.targetPath)即转换类型 目标路径共同构成缓存键。这意味着相同目标路径下只有模板源内容变化才会触发重新执行。路径规范化目标路径会先经过paths.ToSlashTrimLeading处理去除前导斜杠、统一为/分隔因此传css/main.css或/css/main.css效果一致。解析与执行分离先通过模板存储tplimpl.TemplateStoreProvider的TextParse把资源内容解析为模板实例再把上下文t.data通过ExecuteWithContext写入输出流。模板解析失败时会返回带有failed to parse Resource %q as Template前缀的错误。上下文贯通ExecuteWithContext接收的是带context.Context的调用链模板执行过程中的Ti18n 翻译、relLangURL等函数都能正常工作——这一点由集成测试验证见下文多语言场景。实战示例用站点配置填充 CSS原文档给出了一个非常典型的应用把站点参数注入 CSS 文件。假设你在assets/css/template.css中有一个 CSS 模板body { background-color: {{ site.Params.style.bg_color }}; color: {{ site.Params.style.text_color }}; }项目配置hugo.toml中包含[params.style] bg_color #fefefe text_color #222在baseof.html布局模板中组合使用{{ with resources.Get css/template.css }} {{ with resources.ExecuteAsTemplate css/main.css $ . }} link relstylesheet href{{ .RelPermalink }} {{ end }} {{ end }}这个示例的工作流程分三步捕获模板资源resources.Get css/template.css从assets目录加载源资源以页面为上下文执行模板resources.ExecuteAsTemplate css/main.css $ .中$是当前页面上下文模板里可用.Title、.Kind等页面属性.是被 with 捕获的 CSS 资源模板内的site.Params.style.bg_color与site.Params.style.text_color分别被替换为#fefefe和#222发布资源访问.RelPermalink触发发布最终生成public/css/main.cssbody { background-color: #fefefe; color: #222; }link标签的href指向/css/main.css浏览器即可加载这份由配置驱动的样式文件。管道链式加工ExecuteAsTemplate 只是起点ExecuteAsTemplate的返回值仍然是普通Resource因此可以继续接入 Hugo Pipes 的其他转换。在 resource_chain_test.go 的集成测试中展示了完整的链式用法——从字符串生成模板资源执行模板后用toCSS转成 SCSS 再压缩最后与其他资源Concat合并{{ $scssFromTempl : .{{ .Kind }} { color: blue; } | resources.FromString kindofblue.templ | resources.ExecuteAsTemplate kindofblue.scss . | toCSS (dict targetPath styles/templ.css) | minify }} {{ $bundle1 : slice $scssFromTempl $scssMin | resources.Concat styles/bundle1.css }}测试断言最终public/styles/bundle1.css内容为.home{color:blue}body{color:#333}证明模板中.Kind被替换为页面类型home且经过toCSS与minify后内容被正确压缩。这种字符串 → 模板 → CSS → 合并的组合非常适合生成动态主题或品牌色变量文件。多语言场景验证ExecuteAsTemplate执行的模板支持完整的 Hugo 模板函数集包括 i18n 翻译函数T。集成测试 templates_integration_test.go 构造了一个法语为默认语言、英语与法语并存的站点{{ $templ : {{T \hello\}} | resources.FromString f1.html }} {{ $helloResource : $templ | resources.ExecuteAsTemplate (print f%s.html .Lang) . }} Hello1: {{T hello}} Hello2: {{ $helloResource.Content }}测试断言public/en/index.html与public/fr/index.html中Hello2分别输出Hello与Bonjour——说明模板执行时正确读取了各语言自己的i18n翻译表。同时注意这里的目标路径用print f%s.html .Lang动态拼接如fen.html、ffr.html这正体现了targetPath 是缓存键这一设计不同语言生成不同目标路径各自独立缓存、互不覆盖这是多语言站点使用该函数的推荐写法。常用组合与注意事项从字符串创建模板配合resources.FromString可以从纯字符串直接构建模板资源再执行如{{ .Kind | upper }} | resources.FromString mytpl.txt | resources.ExecuteAsTemplate result.txt .见 resource_chain_test.go。发布时机只有调用Publish、Permalink、RelPermalink之一时资源才会被写入public目录只调用Content读取内容不会触发发布。若想拿到内容字符串可访问.Content。缓存语义结果以execute-as-template targetPath 为键缓存。模板内容或上下文变化但目标路径不变时Hugo 会依据其资源缓存机制内容哈希判断是否重新执行。上下文作用域模板执行时.即你传入的 CONTEXT与页面模板无关需要访问站点配置请使用全局site需要访问页面属性请传入页面对象如$并在模板中用{{ .Title }}取用。错误定位模板语法错误会以failed to parse Resource %q as Template形式返回同时携带资源路径信息便于定位到出错的模板文件。延伸阅读函数官方文档docs/content/en/functions/resources/ExecuteAsTemplate.mdHugo Pipes 总览资源从模板生成docs/content/en/hugo-pipes/resource-from-template.md核心实现resources/resource_transformers/templates/execute_as_template.go模板命名空间入口tpl/resources/resources.go多语言集成测试resources/resource_transformers/templates/templates_integration_test.go链式管道测试用例hugolib/resource_chain_test.go资源发布相关方法Publish、Permalink、RelPermalink【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表