davo36
davo36

Reputation: 714

Golang Templates Header with Dynamic Content

I have a small webserver written in Golang which runs on a bunch of unix devices. I want the name of the device in the header of each page served by my webserver so that I can tell which device I'm looking at.

The webserver has half a dozen web pages, and they all use a nested header template. Like this:

<body>
    {{template "header"}}

And the header.html file could be something like:

{{define "header"}}
    <h1>Device Name is: {{.}}</h1>
{{end}}

I want the name of the device (which is obtained through os.HostName()) to be in the header- and I can't figure out how to do it easily.

What I can do is get the host name at the start of the program, and then pass this back to the HTML every time I call ExecuteTemplate. And as I say, there are around 6 pages, so 6 handlers where I'd have to pass this name back via ExecuteTemplate in my handler function like this. Like this:

func XYZHandler(w http.ResponseWriter, r *http.Request) {
    type returnInfo struct {
        Name        string
    }
    XYZReturnInfo := returnInfo{Name: deviceName} // deviceName obtained at start of program
    tmpl.ExecuteTemplate(w, "XYZ.html", returnInfo )
}

And then the HTML page injects that into the header using .Name.

But is there some way I can put that deviceName value into the header template once at the start of the program? So that then it gets nested into each page from then on?

I should add I'm parsing my .html files at startup too. Using ParseFiles.

Upvotes: 2

Views: 2794

Answers (1)

Thundercat
Thundercat

Reputation: 120951

Add os.HostName as a template function. Call that function in the header.

Here's an example of defining the function when parsing the template:

t := template.Must(template.New("").Funcs(
    template.FuncMap{"hostname": os.Hostname}).ParseFiles(fnames...))

Use the function like this:

{{define "header"}}
    <h1>Device Name is: {{hostname}}</h1>
{{end}}

Run it on the Playground.

Upvotes: 3

Related Questions