4.07 Go Web程序(6)|Go主题月

294 阅读2分钟

  上一章节中,我们介绍了如何给我们的程序添加一个页面显示模板,而且是通过动态配置的,不是硬编码进行的,接下来我们对此进行完善。

代码

我们现在正在使用模板,让我们为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进行添加,避免用户请求错误。