view.html

<h1>www.golangweb.com</h1> <h1>{{.Title |html}}</h1> <div>{{printf "%s" .Body |html}}</div> <p>[<a href="/edit/{{.Title |html}}">edit</a>]</p>

edit.html

<h1>Editing {{.Title |html}}</h1>

<form action="/save/{{.Title |html}}" method="POST">

<div><textarea name="body" rows="20" cols="80">{{printf "%s" .Body |html}}</textarea></div>

<div><input type="submit" value="Save"></div>

</form>

tt.txt

  1. shsussnahdadss

template.go

package main



import (

        "fmt"

        "html/template"

        "io/ioutil"

        "net/http"

        "regexp"

)



type Page struct {

        Title string

        Body  []byte

}



func (p *Page) save() string {

        filename := p.Title + ".txt"

        eer := ioutil.WriteFile(filename, p.Body, 0600)

        if eer != nil {

                return "err"

        }

        return ""

}



func loadPage(title string) (*Page, string) {

        filename := title + ".txt"

        body, err := ioutil.ReadFile(filename)

        if err != nil {

                return nil, err.Error()

        }

        return &Page{Title: title, Body: body}, ""

}



// 查看数据

func viewHandler(w http.ResponseWriter, r *http.Request, title string) {

        p, _ := loadPage(title)

        if p == 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 len(err) == 0 {

                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 len(err) == 0 {

                // http.Error(w, err.Error(), http.StatusInternalServerError)

                return

        }

        http.Redirect(w, r, "/view/"+title, http.StatusFound)

}



// 保存全局的变量的数据

var templates map[string]*template.Template



// 初始化函数

func init() {

        templates = make(map[string]*template.Template)

        for _, tmpl := range []string{"edit", "view"} {

                fmt.Println("sssss")

                tt, err := template.ParseFiles(tmpl + ".html")

                if err != nil {

                        fmt.Println("init err ", err.Error())

                        continue

                }

                t := template.Must(tt, nil)

                templates[tmpl] = t

        }

}



func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {

        err := templates[tmpl].Execute(w, p)

        if err != nil {

                http.Error(w, err.Error(), http.StatusInternalServerError)

        }

}



const lenPath = len("/view/")



var titleValidator = regexp.MustCompile("^[a-zA-Z0-9]+$")



func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {

        return func(w http.ResponseWriter, r *http.Request) {

                title := r.URL.Path[lenPath:]

                if !titleValidator.MatchString(title) {

                        http.NotFound(w, r)

                        return

                }

                fn(w, r, title)

        }

}



// 主函数

func main() {

        http.HandleFunc("/view/", makeHandler(viewHandler))

        http.HandleFunc("/edit/", makeHandler(editHandler))

        http.HandleFunc("/save/", makeHandler(saveHandler))

        http.ListenAndServe(":8080", nil)

}