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)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           1231 次  |  
        
|   最近记录:  |