【问题标题】:HTML templates in golanggolang 中的 HTML 模板
【发布时间】:2014-10-13 20:50:25
【问题描述】:

我正在学习本教程: golang tutorial - wiki,除了“其他任务”部分的最后一点之外,我已经设法让一切正常。我的教程实现:

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "html/template"
    "regexp"
)

type Page struct {
    Title string
    Body []byte
}

func (p *Page) save() error {
    filename := "data/" + p.Title + ".txt"
    return ioutil.WriteFile(filename, p.Body, 0600)
}

func loadPage(title string) (*Page, error) {
    filename := "data/" + title + ".txt"
    body, err := ioutil.ReadFile(filename)
    if err != nil {
        return nil, err
    }
    return &Page{Title: title, Body: body}, nil
}

func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
    t, _ := template.ParseFiles("template/" + tmpl + ".html");
    t.Execute(w, p)
}

func viewHandler(w http.ResponseWriter, r *http.Request) {
    title := r.URL.Path[len("/view/"):]
    p, err := loadPage(title)
    if err != nil {
        http.Redirect(w, r, "/edit/" + title, http.StatusFound);
        return
    }
    expr := regexp.MustCompile(`\[.+\]`)
    p.Body = expr.ReplaceAllFunc(p.Body, func ( match []byte) []byte {
        return []byte("<a href='/view/" + string(match) + "'>" + string(match) + "</a>")
    })
    renderTemplate(w, "view", p);
}

func saveHandler(w http.ResponseWriter, r *http.Request) {
    title := r.URL.Path[len("/save/"):]
    body := r.FormValue("body")
    p := &Page{Title: title, Body: []byte(body)}
    p.save()
    http.Redirect(w, r, "/view/" + title, http.StatusFound)
}

func editHandler(w http.ResponseWriter, r *http.Request) {
    title := r.URL.Path[len("/edit/"):]
    p, err := loadPage(title);

    if err != nil {
        p = &Page{Title: title}
    }
    renderTemplate(w, "edit", p);
}

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        http.Redirect(w, r, "/view/index", http.StatusFound)    
        })
    http.HandleFunc("/view/", viewHandler)
    http.HandleFunc("/edit/", editHandler)
    http.HandleFunc("/save/", saveHandler)
    http.ListenAndServe(":8080", nil)
    fmt.Println("Running");
}

html/template 引擎按预期打印锚标记,但使用 html 实体对其进行转义。我一直找不到合适的方法。

【问题讨论】:

    标签: html templates go


    【解决方案1】:

    使用template.HTML 将正文标记为安全 HTML。

    以下函数将正文转换为 HTML。

    // Move to package-level variable so that it's compile once.
    var linkPat = regexp.MustCompile(`\[.+\]`)
    
    func toHTML(s string) template.HTML {
    
      // Escape everything in the string first to ensure that
      // special characters ('<' for example) are displayed as
      // characters and not treated as markup.
      s = template.HTMLEscapeString(s)
    
      // Insert the links.
      s = linkPat.ReplaceAllStringFunc(s, func(m string) string {
        s = s[1 : len(s)-1]
        return "<a href='/view/" + m + "'>" + m + "</a>"
      })
    
      return template.HTML(s)
    }
    

    使用以下方式渲染页面:

    renderTemplate(w, "edit", map[string]interface{}{
       "Title": p.Body,
       "Body": toHTML(p.Body),
    })
    

    【讨论】:

    • 对我来说有点太快了..并包含在一个更好的功能中。 +1
    猜你喜欢
    • 2017-06-04
    • 1970-01-01
    • 2015-02-20
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-14
    • 2021-06-13
    相关资源
    最近更新 更多