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.
Operator | Example |
---|---|
eq | arg1 == arg2 |
ne | arg1 != arg2 |
lt | arg1 < arg2 |
le | arg1 <= arg2 |
gt | arg1 > arg2 |
ge | arg1 >= 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, inA1
all dots will refer to value{{with .Value}}
A1{{ else }}
A2{{ end }}
means the same as before but if value is empty thenA2
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