上一章节中,我们介绍了如何给我们的程序添加一个页面显示模板,而且是通过动态配置的,不是硬编码进行的,接下来我们对此进行完善。
代码
我们现在正在使用模板,让我们为viewHandler
创建一个名为view.html
的模板:
<h1>{{.Title}}</h1>
<p>[<a href="/edit/{{.Title}}">edit</a>]</p>
<div>{{printf "%s" .Body}}</div>
相应地修改viewHandler
:
func viewHandler(w http.ResponseWriter, r *http.Request) {
title := r.URL.Path[len("/view/"):]
p, _ := loadPage(title)
t, _ := template.ParseFiles("view.html")
t.Execute(w, p)
}
注意,我们在两个处理程序中使用了几乎完全相同的模板代码。让我们通过将模板代码移动到它自己的函数中来删除这个重复:
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
t, _ := template.ParseFiles(tmpl + ".html")
t.Execute(w, p)
}
并修改处理程序以使用该函数:
func viewHandler(w http.ResponseWriter, r *http.Request) {
title := r.URL.Path[len("/view/"):]
p, _ := loadPage(title)
renderTemplate(w, "view", p)
}
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 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
}
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)
}
页面标题(在URL
中提供)和表单唯一的字段Body
存储在一个新页面中。然后调用save()
方法将数据写入文件,客户端被重定向到/view/page
。
FormValue
返回的值是string
类型的。我们必须将该值转换为[]byte
,然后它才能适合页面结构。使用[]byte(body)
执行转换。
总结
本节主要是将对应的两个编辑页面补全,同时将对应的不存在的页面的
handler
进行添加,避免用户请求错误。