Roe*_*ink 4 html go go-templates
我已经开始使用 Go 语言,现在正在尝试创建一个 HTML 页面。我对 Go 和 HTML 编码都很陌生。
在 Go 程序中,我试图将 HTML 页面 (div) 解析为主 html 页面 (index.html) 我试图使用 Go 中的模板将此 div 添加到主 html 页面。
我试图将数据解析成的 html 页面如下所示:
<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>
Run Code Online (Sandbox Code Playgroud)
{{.SonoffBasic}} 部分是我尝试添加 div 的部分。我要添加的 div 如下所示:
<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>
Run Code Online (Sandbox Code Playgroud)
所有带有 %xxx% 的值都在 go 中解析以包含有用的信息,并且一切正常。
但是现在我正在尝试使用 Go 中的模板将这两个一起解析,这里似乎出了点问题。
我在 Go 中使用以下函数执行此操作:
func renderHomeKitTemplate(w http.ResponseWriter, tmpl string, items *WebPageHTMLItems) {
err := templates.ExecuteTemplate(w, "index.html", items)
}
Run Code Online (Sandbox Code Playgroud)
其中变量 items 是一个如下所示的结构:
type WebPageHTMLItems struct{
SonoffBasic string
}
Run Code Online (Sandbox Code Playgroud)
其中 theSonoffBasic 字符串包含所有填充信息的 div。
当我运行程序时可以查看网页,但是当显示网页时,它不是解析div,而是显示为纯文本,我在这里做错了什么?

这甚至是将数据解析为 HTML 文件的正确方法吗?我使用这种添加完整 div 的方式的原因是因为我可以有多个“sonoffbasicdevice”项目并且应该添加多个项目。
template.HTMLhtml/template 提供针对代码注入的自动、上下文敏感的安全转义:
HTML 模板将数据值视为应该进行编码的纯文本,以便它们可以安全地嵌入到 HTML 文档中。转义是上下文相关的,因此操作可以出现在 JavaScript、CSS 和 URI 上下文中。
包中有一个特殊类型html/template:template.HTML. 呈现模板时,模板中这种类型的值不会被转义。
因此,更改WebPageHTMLItems.SonoffBasicto的类型,template.HTML它将按原样呈现:
type WebPageHTMLItems struct{
SonoffBasic template.HTML
}
Run Code Online (Sandbox Code Playgroud)
template.HTML具有string作为其基础类型,因此要从string值设置此字段,请使用简单的类型转换:
params := &WebPageHTMLItems{
SonoffBasic: template.HTML("<div>...</div>"),
}
Run Code Online (Sandbox Code Playgroud)
警告:这不能防止代码注入!因此,例如,当您替换%title%并且它包含 JavaScript 代码时,它将被传递到输出并最终在客户端的浏览器中执行。
{{template}}动作另请注意,您可以将您定义<div>为一个单独的命名模板,然后只需使用{{template}}操作将其包含在您的页面中,如下所示:
{{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}}
Run Code Online (Sandbox Code Playgroud)
在您的页面模板中:
<div id="wrapper" width="100%">
{{template "sonoffbasicdevice"}}
</div>
Run Code Online (Sandbox Code Playgroud)
另请注意,为了完全安全,您还可以sonoffbasicdevice像其他任何模板一样制作参数并将其传递给您的模板,并让html/template包处理安全的、上下文相关的替换:
{{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}}
Run Code Online (Sandbox Code Playgroud)
然后你必须像这样包含它(传递用于它的参数):
<div id="wrapper" width="100%">
{{template "sonoffbasicdevice" .SonoffBasic}}
</div>
Run Code Online (Sandbox Code Playgroud)
这个“多模板”的执行可能如下所示:
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)
Run Code Online (Sandbox Code Playgroud)