Home > Software design >  What is the difference between running a function in a .go file and invoking it in Go template?
What is the difference between running a function in a .go file and invoking it in Go template?

Time:02-04

With template.FuncMap from the text/template package, you can directly access functions from within your Go template files.

Suppose the following scenario: In your handler for a user overview page, you call a function GetAllUsers and pass your user objects to the template with ExecuteTemplate:

func index(w http.ResponseWriter, r *http.Request) {
  users, err := model.GetAllUsers()
  if err != nil {
    render50x()
    return
  }

  data := make(map[string]interface{})
  data["userList"] = users

  render(w, r, data, "layout", "index")
}

Is this the same as passing the function to the template and executing it there?

var funcs = template.FuncMap{
  "getAllUsers": model.GetAllUsers,
}

// func render
t := template.New("render").Funcs(funcs)
if err := template.Must(t.ParseFS(ViewsFS, files...)).ExecuteTemplate(w, layout, data); err != nil {
  log.Println("Error executing template:", err.Error())
}

{{ range getAllUsers }}
  {{ .DisplayName }}
{{ end }}

Is there a difference between the two approaches?

CodePudding user response:

If you can call the function from the template, it's the same. Some differences:

If you call it in Go, you do not need to register the function. Sometimes you don't have access to template parsing to register functions, so this is the only way (don't forget: you have to register functions before parsing the template).

Also if you call it in Go, you have more "control" over it: you can recover from panics, you can pre-process the results, and you can re-use it in other Go code. You can also choose not to execute the template based on the result, or do something else which may not be (easily) expressible in templates.

The result of the function may also not be something that can be rendered easily. E.g. it may not be a string, or may not have a String() string method. So some additional (Go) logic may be needed to convert the result to a human-readable format, which may not be available in templates, or may require further functions to be registered.

Also note that not all functions can be registered and called from templates. Callable functions may have 2 return types at most, the seconds which may only be error. From Go you can call "any" functions and pass only the results you need. If the function has parameters, you also have to pass those as data to the template execution (so you can pass them in the template when calling the function).

  • Related