Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With Golang Templates how can I set a variable in each template?

Tags:

templates

go

How can I set a variable in each template that I can use in other templates e.g.

{{ set title "Title" }}

in one template then in my layout

<title> {{ title }} </title>

Then when it's rendered

tmpl, _ := template.ParseFiles("layout.html", "home.html")

it will set the title according to whatever was set in home.html instead of having to make a struct for each view page when it isn't really necessary. I hope I made sense, thanks.

Just for clarification:

layout.html:
<!DOCTYPE html>
<html>
  <head>
    <title>{{ title }} </title>
  </head>
  <body>

  </body>
</html>

home.html:
{{ set Title "Home" . }}
<h1> {{ Title }} Page </h1>
like image 845
Datsik Avatar asked Jun 03 '15 01:06

Datsik


People also ask

How do I declare a variable in Go template?

One way to approach this is to declare the variable first to an empty value: {{ $w := "" }} {{ if 1 }} {{ $w = "world" }} {{ else }} {{ $w = "earth" }} {{ end -}} Hello, {{ print $w }}!

How do you call a function in Go template?

According to the documentation, you can call any method which returns one value (of any type) or two values if the second one is of type error . In the later case, Execute will return that error if it is non-nil and stop the execution of the template.

What is Gomplate?

gomplate is a template renderer which supports a growing list of datasources, such as: JSON (including EJSON - encrypted JSON), YAML, AWS EC2 metadata, and secrets. Come chat with developers and community in the on and on ! Please report any bugs found in the .

What are templates in Golang?

Template in Golang is a robust feature to create dynamic content or show customized output to the user. Golang has two packages with templates: text/template. html/template.


1 Answers

If you want to use the Value in another template you can pipeline it to the dot:

{{with $title := "SomeTitle"}}
{{$title}} <--prints the value on the page
{{template "body" .}}
{{end}}

body template:

{{define "body"}}
<h1>{{.}}</h1> <--prints "SomeTitle" again
{{end}}

As far as i know it is not possible to go upwards in the chain. So layout.html gets rendered before home.html, so you cant pass a value back.

In your example it would be the best solution to use a struct and pass it from the layout.html to the home.html using the dot:

main.go

package main

import (
    "html/template"
    "net/http"
)

type WebData struct {
    Title string
}

func homeHandler(w http.ResponseWriter, r *http.Request) {
    tmpl, _ := template.ParseFiles("layout.html", "home.html")
    wd := WebData{
        Title: "Home",
    }
    tmpl.Execute(w, &wd)
}

func pageHandler(w http.ResponseWriter, r *http.Request) {
    tmpl, _ := template.ParseFiles("layout.html", "page.html")
    wd := WebData{
        Title: "Page",
    }
    tmpl.Execute(w, &wd)
}

func main() {
    http.HandleFunc("/home", homeHandler)
    http.HandleFunc("/page", pageHandler)
    http.ListenAndServe(":8080", nil)
}

layout.html

<!DOCTYPE html>
<html>
  <head>
    <title>{{.Title}} </title>
  </head>
  <body>
    {{template "body" .}}
  </body>
</html>

home.html

{{define "body"}}
<h1>home.html {{.Title}}</h1>
{{end}}

page.html

{{define "body"}}
<h1>page.html {{.Title}}</h1>
{{end}}

Also go has a nice documentation on how to use templates:

http://golang.org/pkg/text/template/

like image 63
stonith Avatar answered Sep 28 '22 06:09

stonith