4.06 Go Web程序(5)|Go主题月

256 阅读2分钟

  上节已经成了我们如何通过web访问本地中存在的文件,但是没有编辑页面的能力,wiki就不是wiki。接下来让我们创建两个新处理程序:一个名为editHandler的处理程序用于显示“编辑页面”表单,另一个名为saveHandler的处理程序用于保存通过表单输入的数据。

代码编写

主函数中添加以下代码:

func main() {
    http.HandleFunc("/view/", viewHandler)
    http.HandleFunc("/edit/", editHandler)
    http.HandleFunc("/save/", saveHandler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

函数editHandler加载页面(或者,如果页面不存在,则创建一个空页面结构),并显示一个HTML表单:

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}
    }
    fmt.Fprintf(w, "<h1>Editing %s</h1>"+
        "<form action=\"/save/%s\" method=\"POST\">"+
        "<textarea name=\"body\">%s</textarea><br>"+
        "<input type=\"submit\" value=\"Save\">"+
        "</form>",
        p.Title, p.Title, p.Body)
}

以上是通过硬编码的方式进行HTML的演示,接下来我们可以换一种方式去解决:
html/template包是Go标准库的一部分。我们可以使用html/templatehtml保存在一个单独的文件中,允许我们在不修改底层Go代码的情况下改变编辑页面的布局。
首先我们要修改我们的引用包:

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

让我们创建一个包含HTML表单的模板文件。打开一个名为edit.html的新文件,并添加以下行:

<h1>Editing {{.Title}}</h1>
<form action="/save/{{.Title}}" method="POST">
<div><textarea name="body" rows="20" cols="80">{{printf "%s" .Body}}</textarea></div>
<div><input type="submit" value="Save"></div>
</form>

接下来修改editHandler来使用模板,而不是硬编码的HTML:

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}
    }
    t, _ := template.ParseFiles("edit.html")
    t.Execute(w, p)
}

函数template.ParseFiles将读取edit.html的内容并返回一个template.Template

方法t.Execute执行模板,将生成的HTML写入http.ResponseWriter。带点的.title.body标识符指的是p.Titlep.Body

模板指令用双花括号括起来。printf "%s".body指令是一个函数调用,它将.body输出为字符串而不是字节流,与调用fmt.Printf相同。html/template包有助于保证只有安全的、外观正确的html才会由模板操作生成。例如,它会自动转义任何大于符号(>)的符号,将其替换为&gt;,以确保用户数据不会破坏表单HTML

总结

  以上是将我们页面显示大体搭建好,后面我们还需要将对应的浏览跳转等等增加,即可完成我们需要的东西。