GolangNote

Golang笔记

Golang quicktemplate 模版快速入门

Permalink

Golang 有很多的模版引擎,自带的 html/template 也很好,大多数情况都能满足需求,只是有些逻辑、条件判断不好在模版里实现, quicktemplate 是个很好的选择。

golang 一些预编译模版的性能比较

再看看模版的语法解析,综合性能与语法, quicktemplate 是个非常好的选择。

quicktemplate 入门

下面简单介绍一下 quicktemplate 模版的使用方法,将定义两个页面:首页、用户列表页

新建一个 base.qtpl 文件作为基本页面或叫 layout,规定以 qtpl 为后缀名。

定义 Page interface

Go: Page interface
1
2
3
4
5
6
{% interface
Page {
	Title()
	Body()
}
%}

PageTemplate 函数,以 Page 为参数

Go: PageTemplate
1
2
3
4
5
6
7
8
9
10
{% func PageTemplate(p Page) %}
<html>
	<head>
		<title>{%= p.Title() %}</title>
	</head>
	<body>
		{%= p.Body() %}
	</body>
</html>
{% endfunc %}

定义首页

定义 BasePage struct

Go: BasePage struct
1
2
3
4
{% code type BasePage struct {
    HeadTitle string
    MainBody  string
} %}

给 BasePage 定义 Title()Body() 函数/方法

Go: BasePage 方法
1
2
3
4
5
6
7
8
9
{% func (p *BasePage) Title() %}{%s p.HeadTitle %}{% endfunc %}

{% func (p *BasePage) Body() %}
<div>
    <a href="/users">goto users page</a>
</div>
<h1>{%s p.HeadTitle %}</h1>
<p>{%s p.MainBody %}</p>
{% endfunc %}

这样首页模版就定义好了,首页的 handler 调用:

Go: Home handler
1
2
3
4
5
6
7
8

func Home(w http.ResponseWriter, r *http.Request) {
	p := &templates.BasePage{
		HeadTitle: "Home page",
		MainBody:  "This is a home body",
	}
	templates.WritePageTemplate(w, p)
}

定义用户列表页

新建 users.qtpl 文件

用户列表页可以继承 BasePage struct

Go: UsersPage struct
1
2
3
4
{% code type UsersPage struct {
    BasePage
    Users []string
} %}

这里我只需重新定义 Body() 方法

Go:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{% func (p *UsersPage) Body() %}
<div>
    <a href="/">return to main page</a>
</div>

<h1>{%s p.HeadTitle %}</h1>

<p>{%s p.MainBody %}</p>

{% if len(p.Users) > 0 %}
<ul>
    {% for i, name := range p.Users %}
        <li> {%d i %} - {%s name %}
    {% endfor %}
</ul>
{% endif %}

{% endfunc %}

当然也可以覆盖 Title() 方法,如:

Go: Title
1
{% func (p *BasePage) Title() %}{%s p.HeadTitle %} - balabala {% endfunc %}

对应的 handler

Go: Users handler
1
2
3
4
5
6
7
8
9
10
11
12
func Users(w http.ResponseWriter, r *http.Request) {
	p := &templates.UsersPage{
		BasePage: templates.BasePage{
			HeadTitle: "Users page",
			MainBody:  "This is a Users page body",
		},
		Users: []string{
			"Google", "Baidu", "Bing", "Sogo",
		},
	}
	templates.WritePageTemplate(w, p)
}

当模版有修改后必须在网站根目录(main.go目录)实行命令 qtc templates,templates 是模版文件存放的目录

完整代码

文件结构

plaintext: 文件结构
1
2
3
4
5
6
7
8
├── go.mod
├── go.sum
├── main.go
└── templates
    ├── base.qtpl
    ├── base.qtpl.go
    ├── users.qtpl
    └── users.qtpl.go

其中 *.qtpl.go 文件是实行命令 qtc templates 后自动生成的 go 文件,里面有相应的方法可以 handler 里调用。

以下是完整文件内容

main.go 文件

Go: main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package main

import (
	"net/http"
	"qktp/templates"
)

func main() {
	http.HandleFunc("/users", Users)
	http.HandleFunc("/", Home)
	_ = http.ListenAndServe(":8080", nil)
}

func Home(w http.ResponseWriter, r *http.Request) {
	p := &templates.BasePage{
		HeadTitle: "Home page",
		MainBody:  "This is a home body",
	}
	templates.WritePageTemplate(w, p)
}

func Users(w http.ResponseWriter, r *http.Request) {
	p := &templates.UsersPage{
		BasePage: templates.BasePage{
			HeadTitle: "Users page",
			MainBody:  "This is a Users page body",
		},
		Users: []string{
			"Google", "Baidu", "Bing", "Sogo",
		},
	}
	templates.WritePageTemplate(w, p)
}

templates/base.qtpl 文件

Go: templates/base.qtpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{% interface
Page {
	Title()
	Body()
}
%}


{% func PageTemplate(p Page) %}
<html>
	<head>
		<title>{%= p.Title() %}</title>
	</head>
	<body>
		{%= p.Body() %}
	</body>
</html>
{% endfunc %}


{% code type BasePage struct {
    HeadTitle string
    MainBody  string
} %}

{% func (p *BasePage) Title() %}{%s p.HeadTitle %}{% endfunc %}

{% func (p *BasePage) Body() %}
<div>
    <a href="/users">goto users page</a>
</div>
<h1>{%s p.HeadTitle %}</h1>
<p>{%s p.MainBody %}</p>
{% endfunc %}

templates/users.qtpl 文件

Go: templates/users.qtpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{% code type UsersPage struct {
    BasePage
    Users []string
} %}


{% func (p *UsersPage) Body() %}
<div>
    <a href="/">return to main page</a>
</div>

<h1>{%s p.HeadTitle %}</h1>

<p>{%s p.MainBody %}</p>

{% if len(p.Users) > 0 %}
<ul>
    {% for i, name := range p.Users %}
        <li> {%d i %} - {%s name %}
    {% endfor %}
</ul>
{% endif %}

{% endfunc %}

参考

使用 gin

只需修改 main.go 文件

Go: gin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package main

import (
	"github.com/gin-gonic/gin"
	"qktp/templates"
)

func main() {
	router := gin.Default()

	router.GET("/users", Users)
	router.GET("/", Home)
	_ = router.Run(":8082")
}

func Home(c *gin.Context) {
	p := &templates.BasePage{
		HeadTitle: "Home page",
		MainBody:  "This is a home body",
	}
	templates.WritePageTemplate(c.Writer, p)
}

func Users(c *gin.Context) {
	p := &templates.UsersPage{
		BasePage: templates.BasePage{
			HeadTitle: "Users page",
			MainBody:  "This is a Users page body",
		},
		Users: []string{
			"Google", "Baidu", "Bing", "Sogo",
		},
	}
	templates.WritePageTemplate(c.Writer, p)
}

本文网址: https://golangnote.com/topic/288.html 转摘请注明来源

Related articles

Golang http client 处理重定向网页

假设一个网址有多个重定向,A-B-C-D,使用 http.Client.Get 最后取得的内容是网址D的内容,我们该手动处理包含重定向的网址。...

Golang Web 程序生产环境独立部署示例

一个 web 应用通常是跑在一个前端代理,如 Nginx 后,这样可以方便的在同一个服务器部署多个应用。这里说的独立部署是指让 go web 程序直接暴露在外面,独占 443、80 端口(俗称裸跑)。这样做除了性能有些提高外,更重要的是部署方便。...

Write a Comment to "Golang quicktemplate 模版快速入门"

Submit Comment Login
Based on Golang + fastHTTP + sdb | go1.20 Processed in 15ms