Introduction to the
Recently when we sorted out our project code, we found that there were many active codes that were very similar in structure and functionality. To facilitate future development, I spent some time writing a tool that generates code frameworks to minimize rework. The code itself is not complex and has a lot of relevance to the project code, so I won’t expand on it here. In the process, I found the Go standard template libraries text/template and HTML /template to be rather cumbersome to use. I learned about quickTemplate from GitHub, a third-party template library with powerful functions, simple syntax and easy to use. Today we are going to introduce quickTemplate.
Quick to use
The code in this article uses Go Modules.
Create a code directory and initialize it:
$ mkdir quicktemplate && cd quicktemplate
$ go mod init github.com/darjun/go-daily-lib/quicktemplate
Copy the code
Quicktemplate converts the template code we wrote into the Go language code. So we need to install the QuickTemplate package and a compiler called QTC:
$ go get -u github.com/valyala/quicktemplate
$ go get -u github.com/valyala/quicktemplate/qtc
Copy the code
First, we need to write a template file in QuickTemplate format with a.qtpl extension by default. Here I write a simple template file greeting. QTPL:
All text outside function is treated as comments.
{% func Greeting(name string, count int) %}
{% for i := 0; i < count; i++ %}
Hello, {%s name %}
{% endfor %}
{% endfunc %}
Copy the code
Template syntax is very simple, and there are only two things we need to understand briefly:
- Templates are based on functions, and functions can take any type and number of arguments that can be used in functions. All the text outside the function is a comment,
qtc
Ignore comments at compile time; - Everything inside the function, except the syntax, is printed to the rendered text as is, including whitespace and newlines.
Save greeting. QTPL to the templates directory and run the QTC command. This command generates the corresponding Go file greeting.qtpl. Go, with a package named templates. Now we can use this template:
package main
import (
"fmt"
"github.com/darjun/go-daily-lib/quicktemplate/get-started/templates"
)
func main(a) {
fmt.Println(templates.Greeting("dj".5))}Copy the code
Call the template function, pass in the argument, and return the rendered text:
$ go run .
Hello, dj
Hello, dj
Hello, dj
Hello, dj
Hello, dj
Copy the code
{%s name %} performs text substitution and {% for %} loops to generate duplicate text. Multiple whitespace and line breaks appear in the output because everything inside the function except the syntax is left intact, including whitespace and line breaks.
Note that quickTemplate is used to convert the template to Go code. If the template is modified, you must run the QTC command to regenerate the Go code. Otherwise, the changes will not take effect.
Grammatical structure
Quicktemplate support Go common grammatical structure, if/for/func/import/return. And it’s not that different from writing Go directly, there’s almost no learning cost. However, when using this syntax in templates, it needs to be wrapped with {% and %}, and if and for need to be explicitly terminated by endif/endfor.
variable
We have seen above how to render the passed parameter name using {%s name %}. Since name is a string, use s after {% to specify the type. Quicktemplate also supports other types of values:
- Integer:
{%d int %}
.{%dl int64 %}
.{%dul uint64 %}
; - Floating point Numbers:
{%f float %}
. You can also set the accuracy of the output, using{%f.precision float %}
. For example,{} % f. 2 1.2345%
The output1.23
; - Byte slice (
[]byte
) :{%z bytes %}
; - String:
{%q str %}
Or byte slice:{%qz bytes %}
, the quotation marks escape as"
; - String:
{%j str %}
Or byte slice:{%jz bytes %}
, without quotes; - URL encoding:
{%u str %}
.{%uz bytes %}
; {%v anything %}
: Output is equivalent tofmt.Sprintf("%v", anything)
.
Write the template first:
{% func Types(a int, b float64, c []byte, d string) %}
int: {%d a %}, float64: {%f.2 b %}, bytes: {%z c %}, string with quotes: {%q d %}, string without quotes: {%j d %}.
{% endfunc %}
Copy the code
Then use:
func main(a) {
fmt.Println(templates.Types(1.5.75And []byte{'a'.'b'.'c'}, "hello"))}Copy the code
Run:
$ go run .
int: 1, float64: 5.75.bytes: abc.string with quotes: "hello" .string without quotes: hello.
Copy the code
Call a function
Quicktemplate supports calling template functions and library functions from within templates. Since QTC generates Go code directly, we can even write our own functions to call templates in the same directory, and template A can also call functions defined in template B.
Go, define a rank function, pass in the score, and return the rating:
package templates
func Rank(score int) string {
if score >= 90 {
return "A"
} else if score >= 80 {
return "B"
} else if score >= 70 {
return "C"
} else if score >= 60 {
return "D"
} else {
return "E"}}Copy the code
We can then call this function from the template:
{% import "fmt" %}
{% func ScoreList(name2score map[string]int) %}
{% for name, score := range name2score %}
{%s fmt.Sprintf("%s: score-%d rank-%s", name, score, Rank(score)) %}
{% endfor %}
{% endfunc %}
Copy the code
Compiling templates:
$ qtc
Copy the code
Programming:
func main(a) {
name2score := make(map[string]int)
name2score["dj"] = 85
name2score["lizi"] = 96
name2score["hjw"] = 52
fmt.Println(templates.ScoreList(name2score))
}
Copy the code
Run the program output:
$ go run .
dj: score- 85.rank-B
lizi: score- 96.rank-A
hjw: score- 52rank-E
Copy the code
Since we are using the FMT package in the template, we need to import the package with {% import %} first.
A function that calls another template from within a template is similar, because the template eventually turns into Go code. The Go code has functions with the same signature.
Web
Quicktemplate is commonly used to write templates for HTML pages:
{% func Index(name string) %} <html> <head> <title>Awesome Web</title> </head> <body> <h1>Hi, {%s name %} <p>Welcome to the awesome web!!! </p> </body> </html> {% endfunc %}Copy the code
Let’s write a simple Web server:
func index(w http.ResponseWriter, r *http.Request) {
templates.WriteIndex(w, r.FormValue("name"))}func main(a) {
mux := http.NewServeMux()
mux.HandleFunc("/", index)
server := &http.Server{
Handler: mux,
Addr: ": 8080",
}
log.Fatal(server.ListenAndServe())
}
Copy the code
QTC generates a Write* method that takes an io.Writer argument. To write the template rendering to IO.Writer, we can pass HTTP.ResponseWriter directly as a parameter.
Run:
$ qtc
$ go run .
Copy the code
Browser: localhost:8080? Name = DJ View the result.
conclusion
Quicktemplate has at least three advantages:
- The syntax is very similar to Go and costs almost nothing to learn;
- Will first convert to Go, rendering speed is very fast, than the standard library
html/template
More than 20 times faster; - For security reasons, some coding is performed to prevent attacks.
From my personal use of the actual situation, it is really very convenient, very practical. You can also take a look at the Go code generated by QTC.
If you find a fun and useful Go library, please Go to GitHub and submit issue😄
reference
- Quicktemplate GitHub:github.com/valyala/qui…
- GitHub: github.com/darjun/go-d…
I
My blog is darjun.github. IO
Welcome to follow my wechat public account [GoUpUp], learn together, progress together ~