mirror of
https://github.com/golang/go
synced 2024-11-25 00:47:56 -07:00
44618b28d4
When reading along the article, the extra code added in the final version is not explained. The main function calls flag.Parse(), for example, which will cause an error, unless the readers looks at the entirety of final.go to see the import added. The file shown to the users no longer has the extra flags. The testing code is now in a patch that gets applied to final.go in order to create final-test.go. This is the file that will be used to test the code, matching final.go as much as possible. Change-Id: I022f5f6c88e107c8ba5623661d74a8d260d05266 Reviewed-on: https://go-review.googlesource.com/11061 Reviewed-by: Andrew Gerrand <adg@golang.org>
90 lines
2.1 KiB
Go
90 lines
2.1 KiB
Go
// Copyright 2010 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package main
|
|
|
|
import (
|
|
"html/template"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"regexp"
|
|
)
|
|
|
|
type Page struct {
|
|
Title string
|
|
Body []byte
|
|
}
|
|
|
|
func (p *Page) save() error {
|
|
filename := p.Title + ".txt"
|
|
return ioutil.WriteFile(filename, p.Body, 0600)
|
|
}
|
|
|
|
func loadPage(title string) (*Page, error) {
|
|
filename := title + ".txt"
|
|
body, err := ioutil.ReadFile(filename)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Page{Title: title, Body: body}, nil
|
|
}
|
|
|
|
func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
|
|
p, err := loadPage(title)
|
|
if err != nil {
|
|
http.Redirect(w, r, "/edit/"+title, http.StatusFound)
|
|
return
|
|
}
|
|
renderTemplate(w, "view", p)
|
|
}
|
|
|
|
func editHandler(w http.ResponseWriter, r *http.Request, title string) {
|
|
p, err := loadPage(title)
|
|
if err != nil {
|
|
p = &Page{Title: title}
|
|
}
|
|
renderTemplate(w, "edit", p)
|
|
}
|
|
|
|
func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
|
|
body := r.FormValue("body")
|
|
p := &Page{Title: title, Body: []byte(body)}
|
|
err := p.save()
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
http.Redirect(w, r, "/view/"+title, http.StatusFound)
|
|
}
|
|
|
|
var templates = template.Must(template.ParseFiles("edit.html", "view.html"))
|
|
|
|
func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
|
|
err := templates.ExecuteTemplate(w, tmpl+".html", p)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
}
|
|
}
|
|
|
|
var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")
|
|
|
|
func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
m := validPath.FindStringSubmatch(r.URL.Path)
|
|
if m == nil {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
fn(w, r, m[2])
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
http.HandleFunc("/view/", makeHandler(viewHandler))
|
|
http.HandleFunc("/edit/", makeHandler(editHandler))
|
|
http.HandleFunc("/save/", makeHandler(saveHandler))
|
|
|
|
http.ListenAndServe(":8080", nil)
|
|
}
|