📦 模板打包规范(自包含模板包)
最后更新:2026-10-02
🎯 交付模型
| 角色 | 要做的事 |
|---|---|
| 模板开发者(你) | 做好一整套模板,所有文件放在一个文件夹里,交付该文件夹 |
| 部署 / 运维 | 把文件夹整个放进程序目录的 templates/ 下 |
| 客户 | 后台「站点信息 → 模板路径」下拉里选中它 → 保存。立即生效 |
多语言站点可以各选不同模板:每个站点(含子站)在多站点管理里独立设置自己的模板路径。
📁 推荐目录结构
以模板名 mytheme 为例。文件夹名就是模板名,也是后台下拉里显示的名字,同时是资源 URL 的路径段。
⚠️ 四条硬约束(务必遵守)
1. 所有 .html 必须放在模板文件夹的根层
系统用 ParseGlob(templates/<模板名>/*.html) 加载模板,不递归子目录。放进 mytheme/pages/about.html 的文件不会被加载。子目录只用来放 css/js/图片等资源。
2. 文件夹里至少要有一个 .html,否则不会出现在下拉框
后台下拉只列出「真正的模板包」。一个只装了子目录、根层没有 .html 的文件夹会被自动跳过(否则选中后会静默退回默认模板,表现为「选了没反应」)。
3. 保留名不可用:index 与 admin
templates/index/ 是基模板(兜底层),templates/admin/ 是后台界面模板。这两个名字被系统占用,不会出现在客户的选择列表里,也不要用作你的模板名。
4. 资源必须用 /templates/<模板名>/… 绝对路径引用
见下一节。用相对路径(如 css/style.css)在详情页等多级 URL 下会解析错误。
🔗 资源引用约定
模板文件夹里的 css/js/图片通过专用静态路由伺服,URL 规则为 /templates/<模板名>/<相对路径>,与磁盘结构一一对应。
也可以继续使用全站共享的 /static/… 目录(两者并存)。自包含模板推荐一律走 /templates/<模板名>/,这样整包拷走即可复用。
允许的资源扩展名(白名单)
| 类别 | 扩展名 |
|---|---|
| 样式 / 脚本 | .css .js .mjs |
| 图片 | .png .jpg .jpeg .gif .svg .webp .bmp .ico .avif |
| 字体 | .woff .woff2 .ttf .eot .otf |
| 音视频 | .mp4 .webm .ogg .mp3 .wav |
| 数据 / 文档 | .json .xml .txt .csv .pdf |
⚠️ 上传与引用是两回事:上表是前台可引用的静态资源扩展名。后台「上传图片」受更严格限制,仅允许 .jpg .jpeg .png .gif .webp .avif;.svg(有 XSS 风险)与 .bmp 已从上传白名单移除,无法经后台上传(但仍可作为静态资源手动放入 /static/ 引用)。上传的图片会在浏览器端自动压缩并转换为 AVIF(不支持则 WebP)后再提交,且服务端会做真实类型校验兜底——完整机制见 上传图片安全与转 AVIF 一章。
安全说明:.html 及任何非白名单扩展名通过 URL 访问会返回 403,模板源码不会被下载;../ 路径穿越同样被拦截。所以把 .html 和资源放在同一文件夹是安全的。
🧱 叠加机制:只需覆盖你想改的文件
渲染时先加载基模板 templates/index/,再用你的模板文件夹覆盖同名文件。所以模板包不必包含全部页面——没提供的页面自动沿用基模板。
| 你的包里有 | 实际渲染结果 |
|---|---|
index.html + header.html + footer.html | 首页、头尾用你的;其余页面用基模板(但会带上你的头尾) |
| 全部 15 个页面文件 | 完全由你的模板接管 |
只有 index.html | 只有首页是你的样式,其它页面保持基模板外观 |
建议:做完整交付时至少覆盖 index.html、header.html、footer.html 以及各列表/详情页,避免风格割裂。
基模板包含的 15 个页面文件(可覆盖清单)
🚀 最小可用模板包示例
一个只改首页样式的最小包,三个文件即可跑通。
注意示例里的两个要点:详情链接必须用 {{.URL}}(自带站点前缀,多语言子站才正确),资源用 /templates/mytheme/… 绝对路径。
📥 安装与切换步骤
| 步骤 | 操作 |
|---|---|
| 1 | 把模板文件夹(如 mytheme/)整个复制进程序所在目录的 templates/ 下 |
| 2 | 后台 →「站点信息」→「模板路径」下拉,选中 mytheme |
| 3 | 点击保存。系统自动重新加载模板,无需重启进程 |
| 4 | 刷新前台查看效果(若开启了页面缓存,可等约 1 分钟或在后台清理缓存) |
多站点场景:在「多站点管理」里为每个站点分别选择模板路径,各语言站可用不同模板。
🔍 常见问题排查
| 现象 | 原因与解决 |
|---|---|
| 下拉框里看不到我的模板 | 文件夹根层没有任何 .html;或用了保留名 index/admin;或没放进程序目录的 templates/ |
| 选了模板但页面没变化 | 你的 .html 放进了子目录(不被加载,必须在根层);或文件名与基模板不一致导致没有覆盖;或页面缓存未过期 |
| 页面结构对了但没样式、图片裂开 | 资源路径写错。必须是 /templates/<模板名>/css/style.css,不能用相对路径,也不要漏掉开头的 / |
| 某个资源返回 403 | 扩展名不在白名单内(尤其是想直接访问 .html——这是刻意禁止的) |
| 某个资源返回 404 | URL 路径与磁盘实际路径不一致(注意大小写);或文件确实不存在 |
| 多语言子站链接丢了语言前缀 | 详情链接写死了 /news/{{.ID}}。必须改用 {{.URL}} |
改了 .html 但前台还是旧的 | 模板在启动/保存站点时加载。改文件后到后台重新保存一次站点信息即可触发重载 |
✅ 交付前自检清单
| 检查项 | 标准 |
|---|---|
所有 .html 在文件夹根层 | 子目录里没有 .html |
| 资源全部用绝对路径 | 搜一遍确认没有 href="css/、src="images/ 这类相对写法 |
| 模板名与资源路径一致 | 文件夹叫 mytheme,引用就必须是 /templates/mytheme/… |
详情链接用 {{.URL}} | 没有写死 /news/{{.ID}} 等 |
| SEO 变量已接 | {{.PageTitle}} / {{.PageKeywords}} / {{.PageDescription}} |
| 头尾复用 | 用 {{template "header.html" .}} 而非各页复制粘贴 |
| 没有多余大文件 | 清掉设计稿、.psd、node_modules 等(也无法被伺服) |
Gitl.cn云建站 SaaS