当前位置:首页 > 文章列表 > Golang > Go问答 > Go template.ParseFS 使用通配符时如何组织模板目录

Go template.ParseFS 使用通配符时如何组织模板目录

来源:17golang原创 2026-09-14 13:27:09 0浏览 收藏

把模板编进 embed.FS 后,template.ParseFS 的通配符不是按操作系统磁盘路径工作,而是按 fs.FS 的正斜杠路径匹配。比较稳的组织方式是:页面模板、公共片段分目录保存,//go:embed 负责把它们放进同一棵 FS,ParseFS 再用每层都写清楚的模式加载,最后用 ExecuteTemplate 指定页面入口。

要点速览
  • ParseFS 接受的是 path.Match 风格模式,路径分隔符固定使用 /
  • * 只覆盖当前路径层,不能把 templates/** 当成递归通配符。
  • 页面和 partial 用 define 命名,渲染时显式调用 ExecuteTemplate 更稳定。

先把嵌入路径和通配符分成两层

建议先按“页面入口”和“可复用片段”分目录。假设 Go 源文件与 templates 位于同一个包目录,FS 中会保留 templates/ 这个前缀:

templates/
├── pages/
│   ├── home.tmpl
│   └── account.tmpl
└── partials/
    ├── header.tmpl
    └── footer.tmpl

//go:embed 的模式相对当前 Go 源文件所在的包目录;但加载时看到的是 FS 内的路径。因此下面的两个模式不是重复配置:前者决定哪些文件被编译进程序,后者决定本次解析哪些文件。

package main

import (
    "embed"
    "html/template"
)

// templateFS 把页面和公共片段保留在同一棵只读文件树中。
//go:embed templates/pages/*.tmpl templates/partials/*.tmpl
var templateFS embed.FS

func loadTemplates() (*template.Template, error) {
    // 这里的路径相对 templateFS 根目录,不是当前进程工作目录。
    return template.ParseFS(templateFS,
        "templates/pages/*.tmpl",
        "templates/partials/*.tmpl",
    )
}
Go embed.FS 保留 templates 页面与 partial 目录前缀的结构示意图
图1:Go embed.FS 与 ParseFS 路径分层的结构示意图,页面和公共片段使用同一 FS 前缀。

多级目录不要依赖 **,用显式模式表达边界

ParseFS 使用 path.Match 规则。templates/pages/*.tmpl 能匹配 pages 下一层的文件,但不会继续进入 pages/admin/。Go 的这套模式没有把 ** 定义成“任意深度递归”,所以多级目录应明确写出层数,例如:

func loadAllTemplates() (*template.Template, error) {
    // 每个模式都要至少命中一个文件,否则 ParseFS 返回错误。
    return template.ParseFS(templateFS,
        "templates/partials/*.tmpl",
        "templates/pages/*.tmpl",
        "templates/pages/admin/*.tmpl",
    )
}

如果目录层级经常变化,可以把模板文件统一放到一层,或者在启动时用 fs.Glob 先得到匹配结果,再把明确的文件名交给解析逻辑。不要把一个看似递归、实际不会命中的模式留到生产环境。模式中的路径也不要用 filepath.Join 拼接;io/fs 约定的是 UTF-8、无根、正斜杠路径。

Go template.ParseFS 用单层与多层 path.Match 模式区分模板目录的示意图
图2:ParseFS 通配符层级示意图,单层 * 与显式多层模式分别覆盖不同目录边界。

用命名模板承担页面组合

通配符只负责找文件,不应该承担“哪个页面是入口”的业务含义。让每个文件用 define 暴露稳定名称,页面里再引用公共片段:

{{/* 公共片段使用稳定名称,不依赖文件名 */}}
{{define "header"}}
{{.Title}}
{{end}} {{/* 页面入口显式调用 header,便于 ExecuteTemplate 选择 */}} {{define "home"}}{{template "header" .}}
首页
{{end}}
func renderHome(w io.Writer, data any) error {
    tmpl, err := loadTemplates()
    if err != nil {
        // 启动阶段直接返回加载错误,避免请求时才发现模板缺失。
        return fmt.Errorf("load templates: %w", err)
    }
    // 显式指定 home,避免依赖通配符命中文件的顺序和基础文件名。
    return tmpl.ExecuteTemplate(w, "home", data)
}

如果多个目录存在同名文件,命名模板和解析模式都应保持唯一;页面入口不要只依赖 Execute 默认选择的模板名。这样新增后台页面或替换 partial 时,影响范围更容易判断。

新增模板前先做这张检查表

检查项正确判断常见误区
路径基准以 embed.FS 根目录为准按进程启动目录填写
分隔符使用 /filepath.Join 生成平台路径
层级每层用明确模式覆盖认为 ** 会递归
空匹配启动时处理 ParseFS 错误等到首次请求才发现文件漏编译
执行入口使用 ExecuteTemplate 和稳定名称依赖通配符顺序决定首页

常见问题

templates/*.tmpl 能匹配 templates 子目录吗?

不能。* 不跨越斜杠;子目录要写成独立模式,或调整目录布局。

ParseFS 可以传绝对路径吗?

不适合这样做。它读取的是 fs.FS 的虚拟路径,应传相对 FS 根目录的无根路径。

为什么建议 ExecuteTemplate 而不是 Execute?

多个文件被解析后会形成关联模板集合。显式传入页面定义名,能把渲染入口与文件命中顺序解耦。

实际落地时,只要记住“embed 决定文件进入 FS,ParseFS 决定本次匹配,ExecuteTemplate 决定最终入口”这三个边界,多级模板目录就不容易因为一个通配符写错而在部署后才暴露问题。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
MySQL EXISTS 和 IN 遇到 NULL 条件时有什么区别MySQL EXISTS 和 IN 遇到 NULL 条件时有什么区别
上一篇
MySQL EXISTS 和 IN 遇到 NULL 条件时有什么区别
SkildArt AIGC营销素材生成如何提高效率?可复用的操作流程
下一篇
SkildArt AIGC营销素材生成如何提高效率?可复用的操作流程
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    19次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    125次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    49次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    17次使用
  • OpenCompass大模型评测体系详解:功能、使用指南与应用场景
    OpenCompass
    OpenCompass是上海AI实验室推出的开源大模型评测平台,提供CompassKit、CompassHub和CompassRank三大核心组件,支持LLM及多模态模型的一站式标准化评估与排行榜查询。
    70次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码