quicktemplate 高性能的golang模版引擎
quicktemplate 的设计与其他模版引擎的模式有点不一样,而是直接将代码逻辑嵌入到代码中
同时也会编译到二进制文件中(所以不支持on fly changing)
主要的几个场景
- 做为模版引擎(简化代码的编写,不需要处理复杂的逻辑,对于内容的生成quicktemplate自动生成了,同时可以基于代码的强类型能力调用)
- 做为代码的自动生成工具 (facebook的ent 对于orm 的处理就是基于此模式,高效而且很不错)
参考使用
- 项目结构
├── Makefile
├── README.md
├── demoapp
├── generate.go
├── go.mod
├── go.sum
├── main.go
└── templates
├── code.qtpl
├── code.qtpl.go
├── greetings.qtpl
├── greetings.qtpl.go
├── hello.qtpl
├── hello.qtpl.go
├── page.qtpl
└── page.qtpl.go
- 模版代码
page.qtpl
This is a base page template. All the other template pages implement this interface.
{% interface
Page {
Title()
Body()
}
%}
Page prints a page implementing Page interface.
{% func PageTemplate(p Page) %}
<html>
<head>
<title>{%= p.Title() %}</title>
</head>
<body>
<h1>this is demo </h1>
<div>
<a href="/">return to main page</a>
</div>
{%= p.Body() %}
</body>
</html>
{% endfunc %}
Base page implementation. Other pages may inherit from it if they need
overriding only certain Page methods
{% code type BasePage struct {
Name string
Age int
} %}
{% func (p *BasePage) Title() %}
{%code
p.Name = "dalongdemoaaaaaaa"
%}
<div>
main title: {%s p.Name %}
</div>
{% endfunc %}
{% func (p *BasePage) Body() %}
<div>
main body: {%d p.Age %}
</div>
{% endfunc %}
- main.go
说明以上是一个基于fasthttp+quicktemplate 的简单的web server.main 入口集成了fasthttp
package main
import (
"bytes"
"demoapp/templates"
"github.com/valyala/fasthttp"
)
type login struct {
Name string
Age int
}
func index(ctx *fasthttp.RequestCtx) {
mypage := &templates.BasePage{
Name: "dalong",
Age: 33,
}
var buf bytes.Buffer
templates.WritePageTemplate(&buf, mypage)
ctx.SetContentType("text/html; charset=utf8")
// Set arbitrary headers
ctx.Response.Header.Set("X-My-Header", "my-header-value")
ctx.Write(buf.Bytes())
}
func notFound(ctx *fasthttp.RequestCtx) {
ctx.SetStatusCode(fasthttp.StatusNotFound)
ctx.WriteString("not found ")
}
func (l *login) demo(ctx *fasthttp.RequestCtx) {
switch string(ctx.Path()) {
case "/":
index(ctx)
default:
notFound(ctx)
}
}
func main() {
myHandler := &login{
Name: "dalong",
Age: 333,
}
fasthttp.ListenAndServe(":8080", myHandler.demo)
}
- Makefile
all: generate
update:
go get -u github.com/valyala/fasthttp
go get -u github.com/valyala/quicktemplate/qtc
generate: update
go generate
vet:
go vet ./
运行
- 构建
make
- 运行
go run main.go
- 效果
说明
quicktemplate 在一些场景就不太合适了,比如需要动态更新的,当然如果我们的代码具有完整的版本规划,而且变动比较少的,quicktemplate 是
一个很不错的选择
参考资料
https://github.com/benbjohnson/ego
https://github.com/sipin/gorazor
https://github.com/valyala/quicktemplate
https://www.makotemplates.org/
https://github.com/facebook/ent