我正在关注本教程: 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);

}


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