I've started using the Go language, and am now trying to create an HTML page. I am quite new to both coding in Go and HTML.
In the Go program I'm trying to parse a HTML page (div) into a main html page (index.html) I'm trying to add this div to the main html page using a template in Go.
The html page where I'm trying to parse the data into looks like this:
<html>
<head>
<meta charset="utf-8">
<title>SmartHomePi Status</title>
<link rel="stylesheet" href="../static/css/style.css">
</head>
<body>
<h1>HomeControl Connection Status</h1>
<div id="wrapper" width="100%">
{{.SonoffBasic}}
</div>
</body>
the {{.SonoffBasic}} part is the part where I'm trying to add my div. The div I'm trying to add looks like this:
<div id="sonoffbasicdevice">
<span class="%connectiondotclass%"></span>
<p id="title">%title%</p>
<p id="tempandhum">%humstatus%</p>
<p id="ipaddress">%ipaddress%</p>
<p id="portnumber">%portnumber%</p>
</div>
All value's with %xxx% are parsed in go to contain useful information, and all goes correct.
But now I'm trying to parse those 2 together using a Template in Go, and here seems to go something wrong.
I'm doing that with the following function in Go:
func renderHomeKitTemplate(w http.ResponseWriter, tmpl string, items *WebPageHTMLItems) {
err := templates.ExecuteTemplate(w, "index.html", items)
}
Where the variable items is a struct looking like this:
type WebPageHTMLItems struct{
SonoffBasic string
}
where theSonoffBasic string contains the div with all filled in information.
The webpage can be viewed when I run the program, but when the webpage is shown, instead of parsing the div, it is shown as plain text, what am I doing wrong in here?
Is this even the correct way to parse the data into the HTML file. The reason why I'm using this way of adding a complete div, is because I can have multiple "sonoffbasicdevice" items and should add multiple of them.
template.HTML
html/template
provides automatic, context-sensitive escaping safe against code injection:
HTML templates treat data values as plain text which should be encoded so they can be safely embedded in an HTML document. The escaping is contextual, so actions can appear within JavaScript, CSS, and URI contexts.
There is a special type in the html/template
package: template.HTML
. Values of this type in the template are not escaped when the template is rendered.
So change the type of WebPageHTMLItems.SonoffBasic
to template.HTML
and it will be rendered as-is:
type WebPageHTMLItems struct{
SonoffBasic template.HTML
}
template.HTML
has string
as its underlying type, so to set this field from a string
value, use a simple type conversion:
params := &WebPageHTMLItems{
SonoffBasic: template.HTML("<div>...</div>"),
}
Word of warning: this will not protect against code injection! So for example when you substitute %title%
and it contains JavaScript code, that will be let through to the output and finally executed in the clients' browsers.
{{template}}
actionAlso note that you may define you <div>
as a separate, named template, and just use the {{template}}
action to include it in your page, something like this:
{{define "sonoffbasicdevice"}}
<div id="sonoffbasicdevice">
<span class="%connectiondotclass%"></span>
<p id="title">%title%</p>
<p id="tempandhum">%humstatus%</p>
<p id="ipaddress">%ipaddress%</p>
<p id="portnumber">%portnumber%</p>
</div>
{{end}}
And in your page template:
<div id="wrapper" width="100%">
{{template "sonoffbasicdevice"}}
</div>
Also note that to be on the completely safe side here, you may also make and pass params to your sonoffbasicdevice
template like to any other, and let the html/template
package take care of safe, context sensitive substitution:
{{define "sonoffbasicdevice"}}
<div id="sonoffbasicdevice">
<span class="{{.Connectiondotclass}}"></span>
<p id="title">{{.Title}}</p>
<p id="tempandhum">{{.Humstatus}}</p>
<p id="ipaddress">{{.Ipaddress}}</p>
<p id="portnumber">{{.Portnumber}}</p>
</div>
{{end}}
Then you have to include it like this (to pass params intended for it):
<div id="wrapper" width="100%">
{{template "sonoffbasicdevice" .SonoffBasic}}
</div>
Execution of this "multi-template" could look like this:
type SonoffBasic struct {
Connectiondotclass string
Title string
Humstatus string
Ipaddress string
Portnumber string
}
type WebPageHTMLItems struct{
SonoffBasic *SonoffBasic
}
params := &WebPageHTMLItems{
SonoffBasic: &SonoffBasic{
Connectiondotclass: "someclass",
Title: "sometitle",
Humstatus: "somestatus",
Ipaddress: "someip",
Portnumber: "someport",
},
}
err := templates.ExecuteTemplate(w, "index.html", params)