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 WebAssembly 了解一下

Go 1.11 起开始支持 WebAssembly ,也就是说以后可以使用任何语言作为“前端语言”来进行 Web 开发。...

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

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

Golang 生成防识别的图片验证码

验证码 captcha 是对抗密码强力破解、垃圾信息的有效方式,一般用于用户注册、登录,当检测到频繁发帖时也会启用验证码。下面介绍用golang 生成防机器识别的图片验证码。...

Golang phantomjs 动态代理实现

phantomjs 是个很优秀的软件,虽然现在被chrome headless 抢了风头,但在某些特定场合,使用phantomjs 还是很方便,这里是介绍使用Go 实现动态代理。...

Golang 时区时差处理方式

个人习惯用 0 时区时间戳记录时间,可以方便转到不同时区,下面介绍 Golang 时区时差处理...

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

Submit Comment Login
Based on Golang + fastHTTP + sdb | go1.18 Processed in 16ms