Revel 项目路径必须以 revel.AppPath 为唯一锚点:conf/app.conf 需位于 revel.AppPath + "/conf/app.conf",app/views/ 是模板唯一根目录且大小写敏感,Layout.html 必须在 app/views/ 下,静态资源通过 /assets/ 访问,所有路径拼接均不可跳过 revel.AppPath。

Revel 项目目录结构不能靠猜,必须以 revel.AppPath 为唯一锚点来理解——所有路径拼接错误,都会在启动或运行时静默失败或报模糊错误(如 “template not found”、“Cannot load database ip from app.conf”)。
conf/app.conf 是配置入口,路径和格式错一个字就 fatal
它必须位于 revel.AppPath + "/conf/app.conf",且是合法 INI 格式。Revel 在 revel.Init() 阶段就加载它,早于任何 controller 初始化。
- 常见错误:把
app.conf放进app/conf/或config/,导致revel.Config.String("db.host")返回空,后续连接数据库时报"Cannot load database ip from app.conf" - 配置项名区分大小写:
http.port有效,HTTP.PORT无效 - 环境段落用
[dev]、[prod],但必须配合REVEL_CONF=prod环境变量才生效;默认读[dev]
app/views/ 是模板唯一根目录,大小写敏感且不可配置
Revel 硬编码扫描 app/views/,不支持改名、移动或添加备用路径。控制器名决定子目录名,大小写必须完全一致。
- 控制器
HomeController→ 必须对应app/views/Home/(首字母大写),app/views/home/或app/views/HomeController/都 404 -
Layout.html必须放在app/views/Layout.html(根目录),放app/views/layouts/main.html就无法被隐式继承,只能显式{{template "layouts/main.html" .}} - 热重载只监听
app/目录,改了app/views/Home/Index.html刷新即生效;但public/css/app.css改了需手动刷新浏览器
app/controllers/ 和 app/models/ 不是“可选模块”,而是编译期契约
Revel 启动时会强制扫描 app/controllers/ 下所有 *Controller.go 文件并注册路由;app/models/ 虽不被框架自动加载,但 Go 包路径必须合法,否则 go build 直接失败。
-
app/controllers/AppController.go必须存在,且所有 controller 结构体需嵌入*revel.Controller,否则路由注册失败 -
app/models/User.go必须声明package models,且所在路径是myapp/app/models;若误放app/utils/User.go并在 controller 中写import "myapp/app/utils",Go 编译器找不到包 - 模板后缀固定为
.html,用.tmpl或.gotmpl会导致ParseTemplatepanic
messages/ 和 public/ 的路径逻辑完全不同
messages/ 是 i18n 加载路径,由 Revel 主动拼接 revel.AppPath + "/messages/";而 public/ 是静态资源物理目录,但 URL 映射固定为 /assets/,不是 /public/。
- i18n 文件必须命名如
home.en、news.zh-CN,放在revel.AppPath + "/messages/"下;硬编码相对路径(如./messages/home.en)会因工作目录不确定而失败 - 静态文件放进
app/public/js/app.js,访问地址只能是http://localhost:8080/assets/js/app.js;写/public/js/app.js一定 404 -
public/下的文件不会被 Revel 自动 serve,需在路由中显式配GET /assets/{file:.*}或调用c.StaticFile()
最易被忽略的是:所有路径依赖都始于 revel.AppPath,而不是当前工作目录、os.Getwd() 或 os.Args[0]——后者在 revel run 或测试环境下极不可靠。一旦你开始手拼路径,就必须从 revel.AppPath 出发,一步都不能跳过。











