Introduction to Function Templates
Apart from accessing fields
in templates, we can also access functions or functions
in Golang. The way to access a function is the same as accessing a field
, but if the function has parameters then we can use additional parameters that are sent when calling the function in the template.
The way to make this call is by using {{.FunctionName}}
this is to call the FunctionName
field or the FunctionName()
function. Another example, such as {{.FunctionName "santekno","hello"}}
means this is the same as calling the function FunctionName("santekno","hello")
.
How to Implement
OK, we will try to create a function that we will later access in the template. Previously, we first created the struct
below.
type MyPage struct {
Name string
}
func (myPage MyPage) SayHello(name string) string {
return "Hello " + name + " , My name is " + myPage.Name
}
Then we create a handler where we will send the function to the template that we will create.
func TemplateFunctionHandler(w http.ResponseWriter, r *http.Request) {
t := template.Must(template.New("FUNCTION").
Parse(`{{ .SayHello "Santekno" }}`))
t.ExecuteTemplate(w, "FUNCTION", Page{
Title: "Hello",
Name: "Santekno",
})
}
After that, we also add the handler function to the mux
function so that it can be accessed in the browser.
mux.HandleFunc("/template-function", TemplateFunctionHandler)
Run the program and access the page that we have defined, then the display Hello Santekno, My name is Santekno
will appear.
Global Functions
In Golang templates there are several global functions. Global functions are functions that can be used directly without using a data template. The following are several global Golang Template functions that can be accessed here. https://github.com/golang/go/blob/master/src/text/template/funcs.go
OK, we will try using this Global Function in the template by creating a handler function first.
func TemplateGlobalFunctionHandler(w http.ResponseWriter, r *http.Request) {
t := template.Must(template.New("FUNCTION").
Parse(`{{ len .Name }}`))
t.ExecuteTemplate(w, "FUNCTION", Page{
Title: "Hello",
Name: "Santekno",
})
}
Then add another handler function to the router.
mux.HandleFunc("/template-global-function", TemplateGlobalFunctionHandler)
Rebuild and run the program again, it will display the result 8
. If you look at it, because the .Name
variable is filled with Santekno
, the number of letters for Santekno
is 8.
Added Manual Global Function
We can also add global functions manually, where to add global functions manually, we can use the Funcs
method in the template. Please remember that adding global functions must be done before parsing the template.
First, we will create the handler template as below.
func TemplateManualGlobalFunctionHandler(w http.ResponseWriter, r *http.Request) {
t := template.New("FUNCTION")
t.Funcs(template.FuncMap{
"upper": func(value string) string {
return strings.ToUpper(value)
},
})
t = template.Must(t.Parse(`{{ upper .Name }}`))
t.ExecuteTemplate(w, "FUNCTION", Page{
Title: "Hello",
Name: "Santekno",
})
}
then also add the handler as below.
mux.HandleFunc("/template-manual-global-function", TemplateManualGlobalFunctionHandler)
Finally, we run what we have created with terminal commands
go build && ./learn-golang-web
The results will also display in the browser SANTEKNO
in all capital letters because we have created a custom function that has been registered in the template.
Function Pipelines
Golang templates support function pipelines where the results of one function can be sent to the next function. If we want to use function pipelines, we can use the |
sign, for example:
- {{ sayHello .Name | upper }} means we will call the global function
sayHello(Name)
then the results of that function will be sent to theupper(Result)
function. And in this Golang template we can add more than one function pipeline.
Let’s try adding more by creating a new handler like the one below.
func TemplateFunctionPipelinesHandler(w http.ResponseWriter, r *http.Request) {
t := template.New("FUNCTION")
t.Funcs(template.FuncMap{
"sayHello": func(name string) string {
return "Hello " + name
},
"upper": func(value string) string {
return strings.ToUpper(value)
},
})
t = template.Must(t.Parse(`{{ sayHello .Name | upper }}`))
t.ExecuteTemplate(w, "FUNCTION", Page{
Title: "Hello",
Name: "Santekno",
})
}
Then also add to the router mux
mux.HandleFunc("/template-function-pipelines", TemplateFunctionPipelinesHandler)
Run the program again and look at the results, it will display HELLO SANTEKNO
in all capital letters.