如何在 golang 中使用 gin 服务两个静态站点?
How to serve two static sites with gin in golang?
我想创建一个将调用布尔函数的应用程序,并根据结果提供 2 个已编译 React 应用程序中的 1 个作为静态站点。
我正在使用 gin 推荐的 LoadHTMLGlob 函数,它可以很好地处理 .tmpl 文件,就像他们文档中的示例一样。但是,当只为每个站点使用静态目录执行静态 html 时,似乎一切都不顺利。
文件结构:
├── main.go
└── sites
├── new
│ ├── index.html
│ └── static
└── old
├── index.html
└── static
转到代码:
func main() {
r := gin.Default()
//r.LoadHTMLFiles("sites/old/index.html", "sites/new/index.html") //doesn't complain, but can't load html
r.LoadHTMLGlob("sites/**/*") // complains about /static being a dir on boot
r.GET("/sites/lib", func(c *gin.Context) {
id := c.Query("id")
useNewSite, err := isBetaUser(id)
if err != nil {
c.AbortWithStatusJSON(500, err.Error())
return
}
if useNewSite {
c.HTML(http.StatusOK, "new/index.html", nil)
} else {
c.HTML(http.StatusOK, "old/index.html", nil)
}
})
routerErr := r.Run(":8080")
if routerErr != nil {
panic(routerErr.Error())
}
}
我希望当 isBetaUser 返回为 true 时,它应该加载 sites/new 下的静态内容,否则加载 sites/old.
但是加载 glob 会产生:
panic: read sites/new/static: is a directory
开始恐慌时。
单独加载 html 个文件(上面已注释掉)
运行正常,但是当请求到来时它会出现恐慌:
html/template: "new/index.html" is undefined
我还在 c.HTML
中使用了 sites/[old||new]/index.html
您需要先在模板文件中定义模板,无论是 html/tmpl 文件。像这样,
{{ define "new/index.tmpl" }} ... {{ end }}
或者如果您想坚持使用 html 文件,那么它将是
{{ define "new/index.html" }} ... {{ end }}
。
因此您的模板文件(来自您的示例:sites/new/index.html
)应该如下所示,
{{ define "new/index.html" }}
<html>
<h1>
{{ .title }}
</h1>
<p>New site</p>
</html>
{{ end }}
尝试 sites/**/*.html
修复恐慌。
请注意,Go 使用模板文件的 base 名称作为模板名称,因此要执行模板,您不使用 "path/to/template.html"
,而是使用 "template.html"
.这当然会导致您的情况出现问题,因为如 documentation:
中所述
When parsing multiple files with the same name in different
directories, the last one mentioned will be the one that results.
要解决此问题,您需要明确命名您的模板,您可以使用 {{ define "template_name" }}
操作来完成此操作。
- 打开
sites/new/index.html
- 添加
{{ define "new/index.html" }}
作为第一行
- 添加
{{ end }}
作为最后一行
- 使用
"old/index.html"
作为名称重复 sites/old/index.html
。
我想创建一个将调用布尔函数的应用程序,并根据结果提供 2 个已编译 React 应用程序中的 1 个作为静态站点。
我正在使用 gin 推荐的 LoadHTMLGlob 函数,它可以很好地处理 .tmpl 文件,就像他们文档中的示例一样。但是,当只为每个站点使用静态目录执行静态 html 时,似乎一切都不顺利。
文件结构:
├── main.go
└── sites
├── new
│ ├── index.html
│ └── static
└── old
├── index.html
└── static
转到代码:
func main() {
r := gin.Default()
//r.LoadHTMLFiles("sites/old/index.html", "sites/new/index.html") //doesn't complain, but can't load html
r.LoadHTMLGlob("sites/**/*") // complains about /static being a dir on boot
r.GET("/sites/lib", func(c *gin.Context) {
id := c.Query("id")
useNewSite, err := isBetaUser(id)
if err != nil {
c.AbortWithStatusJSON(500, err.Error())
return
}
if useNewSite {
c.HTML(http.StatusOK, "new/index.html", nil)
} else {
c.HTML(http.StatusOK, "old/index.html", nil)
}
})
routerErr := r.Run(":8080")
if routerErr != nil {
panic(routerErr.Error())
}
}
我希望当 isBetaUser 返回为 true 时,它应该加载 sites/new 下的静态内容,否则加载 sites/old.
但是加载 glob 会产生:
panic: read sites/new/static: is a directory
开始恐慌时。
单独加载 html 个文件(上面已注释掉) 运行正常,但是当请求到来时它会出现恐慌:
html/template: "new/index.html" is undefined
我还在 c.HTML
中使用了 sites/[old||new]/index.html您需要先在模板文件中定义模板,无论是 html/tmpl 文件。像这样,
{{ define "new/index.tmpl" }} ... {{ end }}
或者如果您想坚持使用 html 文件,那么它将是
{{ define "new/index.html" }} ... {{ end }}
。
因此您的模板文件(来自您的示例:sites/new/index.html
)应该如下所示,
{{ define "new/index.html" }}
<html>
<h1>
{{ .title }}
</h1>
<p>New site</p>
</html>
{{ end }}
尝试 sites/**/*.html
修复恐慌。
请注意,Go 使用模板文件的 base 名称作为模板名称,因此要执行模板,您不使用 "path/to/template.html"
,而是使用 "template.html"
.这当然会导致您的情况出现问题,因为如 documentation:
When parsing multiple files with the same name in different directories, the last one mentioned will be the one that results.
要解决此问题,您需要明确命名您的模板,您可以使用 {{ define "template_name" }}
操作来完成此操作。
- 打开
sites/new/index.html
- 添加
{{ define "new/index.html" }}
作为第一行 - 添加
{{ end }}
作为最后一行 - 使用
"old/index.html"
作为名称重复sites/old/index.html
。