zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Eclipse安装Pydev插件时所遇到的问题
    打开Eclipse弹出“No java virtual machine was found..."的解决方法
    使用adb报错;error: unknown host service
    itools安装程序无法创建临时文件夹
    多线程十二之ConcurrentHashMap1.8实现分析
    多线程十一之ConcurrentHashMap1.7源码分析
    多线程十之CopyOnWriteArrayList源码分析
    多线程学习笔记九之ThreadLocal
    多线程学习笔记八之线程池ThreadPoolExecutor实现分析
    多线程学习笔记七之信号量Semaphore
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/14081550.html
Copyright © 2011-2022 走看看