Go开源:hero-高性能、强大并且易用的 Go 模板引擎
wkgv2594
8年前
<h2>Hero</h2> <p>Hero是一个高性能、强大并且易用的go模板引擎,工作原理是把模板预编译为go代码。Hero目前已经在 <a href="/misc/goto?guid=4959735413563244254" rel="nofollow,noindex">bthub.io</a> 的线上环境上使用。</p> <p> </p> <h2>Features</h2> <ul> <li>非常易用.</li> <li>功能强大,支持模板继承和模板include.</li> <li>高性能.</li> <li>自动编译.</li> </ul> <h2>Install</h2> <pre> <code class="language-go">go get github.com/shiyanhui/hero go install github.com/shiyanhui/hero/hero</code></pre> <h2>Usage</h2> <pre> <code class="language-go">hero [options] options: - source: 模板目录,默认为当前目录 - dest: 生成的go代码的目录,如果没有设置的话,和source一样 - pkgname: 生成的go代码包的名称,默认为template - watch: 是否监控模板文件改动并自动编译 example: hero -source="./" hero -source="$GOPATH/src/app/template" -watch</code></pre> <h2>Quick Start</h2> <p>假设我们现在要渲染一个用户列表模板 userlist.html , 它继承自 index.html , 并且一个用户的模板是 user.html . 我们还假设所有的模板都在 $GOPATH/src/app/template 目录下。</p> <h3>index.html</h3> <pre> <code class="language-go"><!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <%@ body { %> <% } %> </body> </html></code></pre> <h3>users.html</h3> <pre> <code class="language-go"><%: func UserList(userList []string) []byte %> <%~ "index.html" %> <%@ body { %> <% for _, user := range userList { %> <ul> <%+ "user.html" %> </ul> <% } %> <% } %></code></pre> <h3>user.html</h3> <pre> <code class="language-go"><li> <%= user %> </li></code></pre> <p>然后我们编译这些模板:</p> <pre> <code class="language-go">hero -source="$GOPATH/src/app/template"</code></pre> <p>编译后,我们将在同一个目录下得到三个go文件,分别是 index.html.go , user.html.go and userlist.html.go , 然后我们在http server里边去调用模板:</p> <h3>main.go</h3> <pre> <code class="language-go">package main import ( "app/template" "net/http" ) func main() { http.HandleFunc("/users", func(w http.ResponseWriter, req *http.Request) { var userList = []string { "Alice", "Bob", "Tom", } w.Write(template.UserList(userList)) }) http.ListenAndServe(":8080", nil) }</code></pre> <p>最后,运行这个http server,访问 http://localhost:8080/users ,我们就能得到我们期待的结果了!</p> <h2>Template syntax</h2> <p>Hero总共有九种语句,他们分别是:</p> <ul> <li> <p>函数定义语句 <%: func define %></p> <ul> <li>该语句定义了该模板所对应的函数,如果一个模板中没有函数定义语句,那么最终结果不会生成对应的函数。</li> <li>该函数必须返回一个 []byte 参数。</li> <li>例: <%: func UserList(userList []string) []byte %></li> </ul> </li> <li> <p>模板继承语句 <%~ "parent template" %></p> <ul> <li>该语句声明要继承的模板。</li> <li>例: <%~ "index.html" ></li> </ul> </li> <li> <p>模板include语句 <%+ "sub template" %></p> <ul> <li>该语句把要include的模板加载进该模板,工作原理和 C++ 中的 #include 有点类似。</li> <li>例: <%+ "user.html" ></li> </ul> </li> <li> <p>包导入语句 <%! go code %></p> <ul> <li> <p>该语句用来声明所有在函数外的代码,包括依赖包导入、全局变量、const等。</p> </li> <li> <p>该语句不会被子模板所继承</p> </li> <li> <p>例:</p> <pre> <code class="language-go"><%! import ( "fmt" "strings" ) var a int const b = "hello, world" func Add(a, b int) int { return a + b } type S struct { Name string } func (s S) String() string { return s.Name } %></code></pre> </li> </ul> </li> <li> <p>块语句 <%@ blockName { %> <% } %></p> <ul> <li> <p>块语句是用来在子模板中重写父模中的同名块,进而实现模板的继承。</p> </li> <li> <p>例:</p> <pre> <code class="language-go"><!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <%@ body { %> <% } %> </body> </html></code></pre> </li> </ul> </li> <li> <p>Go代码语句 <% go code %></p> <ul> <li> <p>该语句定义了函数内部的代码部分。</p> </li> <li> <p>例:</p> <pre> <code class="language-go"><% for _, user := userList { %> <% if user != "Alice" { %> <%= user %> <% } %> <% } %> <% a, b := 1, 2 c := Add(a, b) %></code></pre> </li> </ul> </li> <li> <p>原生值语句 <%== statement %></p> <ul> <li> <p>该语句把变量转换为string。</p> </li> <li> <p>例:</p> <pre> <code class="language-go"><%== a %> <%== a + b %> <%== Add(a, b) %> <%== user.Name %></code></pre> </li> </ul> </li> <li> <p>转义值语句 <%= statement %></p> <ul> <li> <p>该语句把变量转换为string后,又通过 html.EscapesString 记性转义。</p> </li> <li> <p>例:</p> <pre> <code class="language-go"><%= a %> <%= a + b %> <%= Add(a, b) %> <%= user.Name %></code></pre> </li> </ul> </li> <li> <p>注释语句 <%# note %></p> <ul> <li>该语句注释相关模板,注释不会被生成到go代码里边去。</li> <li>例: <# 这是一个注释 > .</li> </ul> </li> </ul> <h2>License</h2> <p>Hero is licensed under the Apache License.</p> <p> </p> <p> </p>