Quantcast
Channel: Hacker News
Viewing all articles
Browse latest Browse all 25817

The fastest go template engine - Hero

$
0
0

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.

GoDocGo Report Card

中文文档

Features

  • High performance.
  • Easy to use.
  • Powerful. template Extend and Include 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 in C++.
    • The sub-template should be quoted with "".
    • Example: <%+ "user.html" >, which we also have mentioned in quick start.
  • 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 by t. Condidates of t are:

      • b: bool
      • i: int, int8, int16, int32, int64
      • u: byte, uint, uint8, uint16, uint32, uint64
      • f: float32, float64
      • s: string
      • bs: []byte
      • v: interface

      Note:

      • If t is not set, the value of t is s.
      • Had better not use v, cause when t=v, the converting method is fmt.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 of Raw Value Statement.
    • Example:

      <%= a %><%=i a + b %><%=u Add(a, b) %><%=bs []byte{1, 2} %>
  • 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.


Viewing all articles
Browse latest Browse all 25817

Trending Articles