README.md
Hero is a handy, fast and powerful go template engine, which pre-compiles the html templates to go code. It has been used in production environment in bthub.io.
Features
- High performance.
- Easy to use.
- Powerful. template
Extend
andInclude
supported. - Auto compiling when files change.
Performance
Hero is the fastest and least-memory used among currently known template engines in the benchmark. The data of chart comes from https://github.com/SlinSo/goTemplateBenchmark. You can find more details and benchmarks from that project.
Install
go get github.com/shiyanhui/hero
go install github.com/shiyanhui/hero/hero
Usage
hero [options]
options:
- source: the html template file or dir.
- dest: generated golang files dir, it will be the same with sourceif not set.
- pkgname: the generated template package name, default is `template`.
- watch: whether automic compile when the source files change.
example:
hero -source="./"
hero -source="$GOPATH/src/app/template" -watch
Quick Start
Assume that we are going to render a user list userlist.html
. index.html
is the layout, and user.html
is an item in the list.
And assumes that they are all under $GOPATH/src/app/template
index.html
<!DOCTYPE html><html><head><metacharset="utf-8"></head><body><%@ body { %><% } %></body></html>
users.html
<%: func UserList(userList []string) *bytes.Buffer %><%~ "index.html" %><%@ body { %><% for _, user := range userList { %><ul><%+ "user.html" %></ul><% } %><% } %>
user.html
Then we compile the templates to go code.
hero -source="$GOPATH/src/app/template"
We will get three new .go
files under $GOPATH/src/app/template
,
i.e. index.html.go
, user.html.go
and userlist.html.go
.
Then we write a http server in $GOPATH/src/app/main.go
.
main.go
package mainimport ("net/http""app/template""github.com/shiyanhui/hero"
)funcmain() {
http.HandleFunc("/users", func(w http.ResponseWriter, req *http.Request) {varuserList = []string {"Alice","Bob","Tom",
}buffer:= template.UserList(userList)defer hero.PutBuffer(buffer)
w.Write(buffer.Bytes())
})
http.ListenAndServe(":8080", nil)
}
At last, start the server and visit http://localhost:8080/users
in your browser, we will get what we want!
Template syntax
There are only nine necessary kinds of statements, which are:
Function Definition
<%: func define %>
- Function definition statement defines the function which represents a html file.
- The function defined should return one and only one parameter
*bytes.Buffer
. - Example:
<%: func UserList(userList []string) *bytes.Buffer %>
, which we have mentioned in quick start.
Extend
<%~ "parent template" %>
- Extend statement states the parent template the current template extends.
- The parent template should be quoted with
""
. - Example:
<%~ "index.html" >
, which we have mentioned in quick start, too.
Include
<%+ "sub template" %>
- Include statement includes a sub-template to the current template. It works like
#include
inC++
. - The sub-template should be quoted with
""
. - Example:
<%+ "user.html" >
, which we also have mentioned in quick start.
- Include statement includes a sub-template to the current template. It works like
Import
<%! go code %>
- Import statement imports the packages used in the defined function, and it also contains everything that is outside of the defined function.
- Import statement will NOT be inherited by child template.
Example:
<%!import ("fmt""strings" )varaintconst b = "hello, world"funcAdd(a, bint) int {return a + b }typeSstruct {Namestring }func (sS) String() string {return s.Name } %>
Block
<%@ blockName { %> <% } %>
Block statement represents a block. Child template overwrites blocks to extend parent template.
Example:
<!DOCTYPE html><html><head><metacharset="utf-8"></head><body><%@ body { %><% } %></body></html>
Code
<% go code %>
Code statement states all code inside the defined function. It's just go code.
Example:
<% for_, user:= userList { %><% if user != "Alice" { %><%= user %><% } %><% } %><%a, b:=1, 2c:=Add(a, b) %>
Raw Value
<%==[t] variable %>
- Raw Value statement will convert the variable to string.
t
is the type of varible, hero will find suitable converting method byt
. Condidates oft
are:b
: booli
: int, int8, int16, int32, int64u
: byte, uint, uint8, uint16, uint32, uint64f
: float32, float64s
: stringbs
: []bytev
: interface
Note:
- If
t
is not set, the value oft
iss
. - Had better not use
v
, cause whent=v
, the converting method isfmt.Sprintf("%v", variable)
and it is very slow.
Example:
<%== "hello" %><%==i 34 %><%==u Add(a, b) %><%==s user.Name %>
Escaped Value
<%=[t] variable %>
- Escaped Value statement is similar with Raw Value statement, but after converting, it will escaped it with
html.EscapesString
. t
is the same with that ofRaw Value Statement
.Example:
<%= a %><%=i a + b %><%=u Add(a, b) %><%=bs []byte{1, 2} %>
- Escaped Value statement is similar with Raw Value statement, but after converting, it will escaped it with
Note
<%# note %>
- Note statement add notes to the template.
- It will not be added to the generated go source.
- Example:
<# this is just a note example>
.
License
Hero is licensed under the Apache License.