How to make html templates recognize a string as html in go

huangapple go评论124阅读模式
英文:

How to make html templates recognize a string as html in go

问题

我有一个来自Go文档教程的维基Web应用程序,想要添加一些内容。其中之一是在首页上列出所有维基条目的列表。我有一个HTML模板,看起来像这样:

  1. <h1>这是维基的首页</h1>
  2. <p>这是条目列表:</p>
  3. <div>
  4. <ul>
  5. {{printf "%s" .Body}}
  6. </ul>
  7. </div>

这是页面的处理程序:

  1. func frontHandler(w http.ResponseWriter, r *http.Request){
  2. entries := getEntries()
  3. p := &Page{Title: "FrontPage", Body: []byte(entries)}
  4. renderTemplate(w, "front", p)
  5. }

我已经将条目列表格式化为适用于HTML的ul,它是一个字符串切片,连接成一个字节切片,格式如下:

  1. <li><a href="/view/page1">page1</a></li>
  2. <li><a href="/view/page2">page2</a></li>

等等,所以我想将其呈现为HTML,而不是像现在这样的纯文本。

我尝试将页面的body从字节切片更改为字符串,并且结果相同。我尝试更改如何渲染页面,以采用专门用于首页的不同结构体作为解决方法,但也没有效果。这是我渲染模板的方式:

  1. func renderTemplate(w http.ResponseWriter, tmpl string, p *Page){
  2. err := templates.ExecuteTemplate(w, tmpl + ".html", p)
  3. if err != nil{
  4. http.Error(w, err.Error(), http.StatusInternalServerError)
  5. }
  6. }

我还尝试了一些在.html文件中显示它的不同方法,而且都没有成功。

非常感谢任何帮助,如果需要更多信息,请告诉我。

英文:

I have a wiki web app from the go docs tutorial and want to add a few things. One of those things is a list of all wiki entries at the front page. I have a html template that looks like this:

  1. &lt;h1&gt;This is the front page of the wiki&lt;/h1&gt;
  2. &lt;p&gt;here is the list of entries:&lt;/p&gt;
  3. &lt;div&gt;
  4. &lt;ul&gt;
  5. {{printf &quot;%s&quot; .Body}}
  6. &lt;/ul&gt;
  7. &lt;/div&gt;

And here is the handler of the page

  1. func frontHandler(w http.ResponseWriter, r *http.Request){
  2. entries := getEntries()
  3. p := &amp;Page{Title: &quot;FrontPage&quot;, Body: []byte(entries)}
  4. renderTemplate(w, &quot;front&quot;, p)
  5. }

I've formatted the list of entries to work as a ul in html, it is a splice of strings joined into one to convert it to a splice of bytes, it is formatted like this:

  1. &lt;li&gt;&lt;a href=&quot;/view/page1&quot;&gt;page1&lt;/a&gt;&lt;/li&gt;
  2. &lt;li&gt;&lt;a href=&quot;/view/page2&quot;&gt;page2&lt;/a&gt;&lt;/li&gt;

and so on, so i would like to render it as html instead of plain text like it is now.

I've tried changing how i pass the body of the page from a splice of bytes to a string and it had the same outcome. I tried changing how i render the page to take a different struct made specifically for the front page as a workaround but it also had no effect. Here is how i render the template

  1. func renderTemplate(w http.ResponseWriter, tmpl string, p *Page){
  2. err := templates.ExecuteTemplate(w, tmpl + &quot;.html&quot;, p)
  3. if err != nil{
  4. http.Error(w, err.Error(), http.StatusInternalServerError)
  5. }
  6. }

I've also tried a few different ways of showing it in the .html file instead of the {{printf &quot;%s&quot; .Body&quot;}} and I've been unsuccessful.

Any help is much appreciated, also let me know if i should provide more info.

答案1

得分: 1

你可以使用Typed strings

根据文档:

默认情况下,该软件包假定所有流水线都会生成纯文本字符串。它会添加必要的转义流水线阶段,以正确且安全地嵌入该纯文本字符串到适当的上下文中。
当数据值不是纯文本时,您可以通过标记其类型来确保它没有过度转义。
来自content.go的HTML、JS、URL和其他类型可以携带安全内容,免于转义。

示例:

base.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <div>
  11. <ul>
  12. {{range .}}{{.}}{{end}} <!-- 循环遍历pipeline(.) -->
  13. </ul>
  14. </div>
  15. </body>
  16. </html>
  1. func frontHandler(w http.ResponseWriter, r *http.Request) {
  2. entry := []string{"<li><a href=\"/view/page1\">page1</a></li>", "<li><a href=\"/view/page2\">page2</a></li>"}
  3. tmpl, err := template.ParseFiles("base.html")
  4. if err != nil {
  5. log.Fatal("Unable to parse")
  6. }
  7. // template.HTML只接受一个字符串,因此我们循环遍历entry切片,并将切片值存储在`HTML`类型的htmlvalues中
  8. var htmlvalues []template.HTML
  9. for _, n := range entry {
  10. htmlEncapsulate := template.HTML(n)
  11. htmlvalues = append(htmlvalues, htmlEncapsulate)
  12. }
  13. tmpl.Execute(w, htmlvalues)
英文:

You can use Typed strings

As per documentation:
>By default, this package assumes that all pipelines produce a plain text string. It adds escaping pipeline stages necessary to correctly and safely embed that plain text string in the appropriate context.
When a data value is not plain text, you can make sure it is not over-escaped by marking it with its type.
Types HTML, JS, URL, and others from content.go can carry safe content that is exempted from escaping.

Example:

base.html

  1. &lt;!DOCTYPE html&gt;
  2. &lt;html lang=&quot;en&quot;&gt;
  3. &lt;head&gt;
  4. &lt;meta charset=&quot;UTF-8&quot; /&gt;
  5. &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;
  6. &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
  7. &lt;title&gt;Document&lt;/title&gt;
  8. &lt;/head&gt;
  9. &lt;body&gt;
  10. &lt;div&gt;
  11. &lt;ul&gt;
  12. {{range .}}{{.}}{{end}} &lt;!-- Loop over the pipeline(.) --&gt;
  13. &lt;/ul&gt;
  14. &lt;/div&gt;
  15. &lt;/body&gt;
  16. &lt;/html&gt;
  1. func frontHandler(w http.ResponseWriter, r *http.Request) {
  2. entry := []string{&quot;&lt;li&gt;&lt;a href=\&quot;/view/page1\&quot;&gt;page1&lt;/a&gt;&lt;/li&gt;&quot;, &quot;&lt;li&gt;&lt;a href=\&quot;/view/page2\&quot;&gt;page2&lt;/a&gt;&lt;/li&gt;&quot;}
  3. tmpl, err := template.ParseFiles(&quot;base.html&quot;)
  4. if err != nil {
  5. log.Fatal(&quot;Unable to parse&quot;)
  6. }
  7. // template.HTML takes only one string, hence we loop over the entry slice
  8. //and store the slice values in htmlvalues of `HTML` type
  9. var htmlvalues []template.HTML
  10. for _, n := range entry {
  11. htmlEncapsulate := template.HTML(n)
  12. htmlvalues = append(htmlvalues, htmlEncapsulate)
  13. }
  14. tmpl.Execute(w, htmlvalues)

huangapple
  • 本文由 发表于 2022年7月29日 21:30:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/73167569.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定