Explain the basic syntax of golang of template

  • 2020-07-21 08:28:15
  • OfStack

The template

When writing dynamic web pages, we often present the immutable parts as templates. The mutable parts are rendered by back-end programs to generate dynamic web pages. golang provides the html/template package to support template rendering.

This article does not discuss the template reading and rendering methods at the back end of golang, but only the basic USES of embedding variables, rendering variables, loops, etc.

variable

When golang renders template, it is possible to accept a variable of type interface{}, which we can read from the template file and render to the template.

There are two commonly used types of incoming parameters. One is struct, and the struct field can be read inside the template for rendering. The other is map[string]interface{}, which can be used within the template for rendering.

I usually use the second one, the efficiency may be a little bit less, but it is convenient to use.

Syntax support in templates, all need to add {{}} to mark.

In the template file,. Represents the current variable, that is, in the acyclic body,. Represents the variable passed in. Suppose we define a structure:


type Article struct {
  ArticleId int
  ArticleContent string
}

So we can pass it in the template


<p>{{.ArticleContent}}<span>{{.ArticleId}}</span></p>

To get and render the contents of the variable into the template. Assuming that the content of the above structure is ArticleId:1 ArticleContent: "hello", the corresponding content of the rendered template is:


<p>hello<span>1</span></p>

Isn't that easy?

Of course, sometimes we need to define a variable. For example, we need to define an article variable and initialize it to "hello". Then we can write like this:


{{$article := "hello"}}

Suppose we wanted to assign the contents of the passed value to article, we could write this:


{{$article := .ArticleContent}}

In this way, we can get the contents of this variable by using {{$article}}.

function

golang's templates are actually very limited in function, and many complex logic cannot be expressed directly using template syntax, so only template functions can be used to bypass it.

First, when the template package creates a new template, it supports the.Funcs method to import a collection of custom functions into the template, and subsequent files rendered by the template support calling these functions directly.

The function set is defined as:


type FuncMap map[string]interface{}

key is the name of the method and value is the function. There is no limit to the number of arguments to the function, but there is a limit to the return value. There are two options: one with only one return value, and one with two return values, but the second must be of type error. The difference between these two functions is that when the second function is called in the template, assuming that the second parameter of the template function does not return null, the rendering step is interrupted and an error is reported.

Within the template file, calling the method is also very simple:


{{funcname .arg1 .arg2}}

Let's say we define a function


func add(left int, right int) int

In the template file, through the call


{{add 1 2}}

You can get

[

3

]

As a result, golang's predefined functions don't have add, so it's a bit of a hassle.

judge

The golang template also supports conditional judgment on if, which currently supports the simplest bool and string types


{{if .condition}}
{{end}}

When.condition is of type bool, then true means execution, and when.condition is of type string, then non-null means execution.

else, else if nesting is also supported


<p>{{.ArticleContent}}<span>{{.ArticleId}}</span></p>
0

Suppose we need a logical judgment, such as "and", "size is not equal to", etc., we need a number of built-in template functions to do this work.

not non

{{if not .condition}}
{{end}}

and and

{{if and .condition1 .condition2}}
{{end}}

or or

{{if or .condition1 .condition2}}
{{end}}

eq equals

{{if eq .var1 .var2}}
{{end}}

ne is not equal to

{{if ne .var1 .var2}}
{{end}}

lt less than (less than)

{{if lt .var1 .var2}}
{{end}}

le is less than or equal to

{{if le .var1 .var2}}
{{end}}

gt is greater than the

{{if gt .var1 .var2}}
{{end}}

ge is greater than or equal to

{{if ge .var1 .var2}}
{{end}}

cycle

template of golang supports range loop to traverse the contents of map and slice, with the syntax as follows:


<p>{{.ArticleContent}}<span>{{.ArticleId}}</span></p>
1

In this range loop, we can access the traversal value through iiv, and there is another traversal method as follows:


<p>{{.ArticleContent}}<span>{{.ArticleId}}</span></p>
2

The value of index or key cannot be accessed in this way. The corresponding value needs to be accessed through


{{range .slice}}
{{.field}}
{{end}}

And, of course, we're using... to access the traversal value, so what if we want to access the external variable in it? In this case, we need to use $. To access external variables


<p>{{.ArticleContent}}<span>{{.ArticleId}}</span></p>
4

Nesting of templates

When writing templates, we often integrate common templates, such as each page has a navigation bar and footer, and we often write it as a single module, allowing all pages to be imported, so that we don't have to repeat the writing.

Any web page has a master template, and we can embed sub-templates within the master template to share modules.

When a template wants to introduce a subtemplate, we use the following statement:


<p>{{.ArticleContent}}<span>{{.ArticleId}}</span></p>
5

This will attempt to load a subtemplate named navbar, and we will also have to define a subtemplate to implement the "navbar" subtemplate.

The sub-template is defined as:


<p>{{.ArticleContent}}<span>{{.ArticleId}}</span></p>
6

The contents between the definitions will be overwritten {{template "navbar"}}

Of course, the child template is separated, so can the child template get the variables of the parent template? Of course, we just have to use it


<p>{{.ArticleContent}}<span>{{.ArticleId}}</span></p>
7

You can then pass the current variable to the child template, which is also quite handy.


Related articles: