programming

11 How to Understanding HTML Template Action in Golang

Introduction to Action Templates

Not only can we render text in templates, but we can also support action commands such as if branching, for loops and so on. For example, suppose we use if branching like this

Branching with one condition

{{if .Value}} A1 {{ end }}

If Value is not empty, then A1 will be executed and if it is empty nothing will be executed

Branching with 2 conditions

{{if .Value}} A1 {{ else }} A2 {{ end }}

If Value is not empty, then A1 will be executed and if it is empty it will execute A2.

Branching with 3 Conditions

{{if .Value1}} A1 {{else if .Value2}} A2 {{ else }} A3 {{ end }}

If Value1 is not empty then A1 will be executed and if Value2 is not empty then it will execute A2 and if not all then A3 will be executed.

Implementation of If Statement Templates

The following is an example of template implementation if we use the If statement condition in the if.html file

<html>
	<body>
		{{if .Name}}
		<h1>Hello {{.Name}}</h1>
		{{else}}
		<h1>Hai</h1>
		{{ end }}
	</body>
</html>

Then we continue by creating a function handler to display the page we have created.

func TemplateActionIfHandler(w http.ResponseWriter, r *http.Request) {
	t := template.Must(template.ParseFiles("./templates/if.html"))
	t.ExecuteTemplate(w, "if.html", map[string]interface{}{
		"Name": "Santekno",
	})
}

In this handler we use map[string]interface{} to send data from the handler. Next, don’t forget to add route to the main.go file so that the page we have created can be accessed in the browser.

mux.HandleFunc("/template-action-if",TemplateActionIfHandler)

Implementation of Operator Statement Templates

Apart from supporting conditions, comparison operators are also supported by the Golang template so we can use them to compare numbers in if statements along with examples of operators.

OperatorExample
eqarg1 == arg2
nearg1 != arg2
ltarg1 < arg2
learg1 <= arg2
gtarg1 > arg2
gearg1 >= arg2

OK, we will try to implement the existing operators using the if statement. You can create a new file with the file name comparator.html with html contents as below.

<html>
	<body>
		{{if ge .Value 80}}
		<h1>Good</h1>
		{{else if ge .Value 60}}
		<h1>Nice Try</h1>
		{{else}}
		<h1>Try Again</h1>
		{{end}}
  </body>
</html>

Why is the operator at the front? This is because this comparison operator is a function or what we often hear function programming. So when we use {{eq First Second}} it will actually call the eq function with First and Second parameters or more familiarly like this eq(First,Second).

Next, we create a handler function with the name TemplateActionComparatorHandler in the file http_handler.go with details like this.

func TemplateActionComparatorHandler(w http.ResponseWriter, r *http.Request) {
	t := template.Must(template.ParseFiles("./templates/comparator.html"))
	t.ExecuteTemplate(w, "comparator.html", map[string]interface{}{
		"Name":  "Santekno",
		"Value": 100,
	})
}

And finally, we also add the handler function to the main.go file.

	mux.HandleFunc("/template-action-comparator", TemplateActionComparatorHandler)

Done, we run our program and it will display the name and value Good because the value of the variable value is 100. Try changing it to 60, what will happen? Then Nice Try will appear.

Loop operations using Range

Range is a loop or iteration operation performed on template data. In Golang, this loop template cannot use for. Usually this data loop uses a range to iterate each data array, slice, map or channel. For example

{{ range $index, $element := .Value }}
	A1
{{ end }}

If Value has data, then A1 will be executed as many times as the element value and we can use $index to access the index and $element to access the element.

Another example like this

{{ range $index, $element := .Value }}
	A1
{{ else }}
	A2
{{ end }}

In this second example, it is actually the same as the first example, but if a value does not have any elements then A2 will be executed.

Let’s try it directly by creating a file range.html with the contents of the html code as below.

<html>
	<body>
		{{range $index, $element := .Hobbies}}
			<h1>{{ $element }}</h1>
		{{else}}
			<h1>Anda tidak punya hobi</h1>
		{{end}}
	</body>
</html>

And next we will create a handler with the template created above.

func TemplateActionRangeHandler(w http.ResponseWriter, r *http.Request) {
	t := template.Must(template.ParseFiles("./templates/range.html"))
	t.ExecuteTemplate(w, "range.html", map[string]interface{}{
		"Hobbies": []string{
			"Gaming", "Reading", "Coding",
		},
	})
}

Continue by creating a handler function as below.

	mux.HandleFunc("/template-action-range", TemplateActionRangeHandler)

Run the program and access the browser, it will display as below.

Gaming
Reading
Coding

With operation

Sometimes we often create a nested struct which if we use a template we can access it by using .Value.NestedValue in the With action template by changing the scope dot to the object we want. An example of this is the case

  • {{with .Value}} A1 {{ end }} means that if value is not empty, in A1 all dots will refer to value
  • {{with .Value}} A1 {{ else }} A2 {{ end }} means the same as before but if value is empty then A2 will be executed

We will try it by creating a template file first like this

<html>
	<body>
			{{/* example comment */}}
			Name : {{.Name}} <br>
			{{with .Address}}
			Address Street : {{.Street}}<br>
			Address City : {{.City}}<br>
			{{end}}
	</body>
</html>

Next we will create a new handler function to read the template file above like this.

func TemplateActionWithHandler(w http.ResponseWriter, r *http.Request) {
	t := template.Must(template.ParseFiles("./templates/address.html"))
	t.ExecuteTemplate(w, "address.html", map[string]interface{}{
		"Name": "Santekno",
		"Address": map[string]interface{}{
			"Street": "Jalan Padjadjaran",
			"City":   "Bogor",
		},
	})
}

Then don’t forget to call the handler function in the main.go file to initialize the endpoint.

mux.HandleFunc("/template-action-with", TemplateActionWithHandler)

Rebuild and try running the program again.

go build && ./learn-golang-web

Once built and run, a display will appear on the browser page once accessed as below

Name : Santekno
Address Street : Jalan Padjadjaran
Address City : Bogor
comments powered by Disqus