简易项目目录结构
```
├── main.go
├── public
│ └── assets
│ ├── css
│ ├── fonts
│ ├── images
│ └── js
└── templates
├── layouts
│ ├── default.html
│ └── single.html
├── partials
│ ├── footer.html
│ └── header.html
└── views
├── login.html
└── index.html
```
main.go
```
package main
import (
"fmt"
"html/template"
"net/http"
)
func main() {
http.HandleFunc("/", home)
http.HandleFunc("/login.html", login)
http.ListenAndServe(":8080", nil)
}
func home(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("templates/views/index.html",
"templates/layouts/single.html",
"templates/layouts/default.html",
"templates/partials/header.html",
"templates/partials/footer.html")
if err != nil {
fmt.Println(err)
}
t.ExecuteTemplate(w, "default", nil)
}
func login(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("templates/views/login.html",
"templates/layouts/default.html",
"templates/layouts/single.html",
"templates/partials/header.html",
"templates/partials/footer.html")
if err != nil {
fmt.Println(err)
}
t.ExecuteTemplate(w, "single", nil)
}
```
templates/layouts/default.html
```
{{ define "default" }}
<!doctype html>
<html lang="en" dir="ltr">
<head>
<title>{{block "title" . }}默认页面模板{{ end }}</title>
</head>
<body class="">
{{ template "content" . }}
</body>
</html>
{{ end }}
```
templates/layouts/single.html
```
{{ define "single" }}
<!doctype html>
<html lang="en" dir="ltr">
<head>
<title>{{block "title" . }}单页面模板,适用于登录、注册{{ end }}</title>
</head>
<body class="">
{{ template "content" . }}
</body>
</html>
{{ end }}
```
templates/views/index.html
```
{{ template "default" }}
{{ define "content" }}
默认页面
{{ end }}
```
templates/views/login.html
```
{{ template "single" }}
{{ define "content" }}
登录页面
{{ end }}
```
这样运行起来没问题,也可以正常渲染,但如果views里面内容很多,甚至有多级子目录,一个一个写太繁琐。
目前是写一个递归扫描templates/views文件存到views数组,然后分别获取templates/layouts,templates/partials,接着遍历views把每个view和layouts+partials组合起来给template.ParseFiles,handler中根据请求的path获取具体的template,然后执行ExecuteTemplate。
问题:如何决定t.ExecuteTemplate(w, "single", nil)中第二个参数?如果写配置会不会太笨了,每个view都要一个配置。
你这样想必应该也是没有问题的,不过我不想搞这样的配置。我的目录结构很清楚了
```
└── templates
├── layouts
│ ├── default.html
│ └── single.html
├── partials
│ ├── footer.html
│ └── header.html
└── views
├── login.html
└── index.html
```
程序启动时,自动递归扫描views下所有的.html文件(模板),对于每一个文件,都和layouts/partials里面的文件合并成一个数组,这个就好像你的JSON配置。
我现在的问题是,如果layout有多个就会出现问题。这样说能明白吗?
#8
更多评论
t.ExecuteTemplate(w, "single", nil)
第二个参数使用当前页面的相对路径,且包含子目录,对上面的代码好像是可以,但是不能获取从代码传过来的数据。
改造:
index.html
```
{{ template "default" }}
{{ define "content" }}
<div>默认页面</div>
<div>{{ . }} </div>
{{ end }}
```
login.html
```
{{ template "single" }}
{{ define "content" }}
<div>登录页面</div>
<div>{{ . }} </div>
{{ end }}
```
简化partials部分的index
```
func home(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("templates/views/index.html",
"templates/layouts/single.html",
"templates/layouts/default.html")
if err != nil {
fmt.Println(err)
}
t.ExecuteTemplate(w, "default", &map[string]interface{}{
"key1": "value1",
})
}
```
第二个参数是default,浏览器显示
```
默认页面
map[key1:value1]
```
第二个参数是index或者index.html,浏览器显示
```
默认页面
```
#2