Go开源:hero-高性能、强大并且易用的 Go 模板引擎

wkgv2594 7年前
   <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>