Skip to content

Instantly share code, notes, and snippets.

@mose
Created September 12, 2013 07:52
Show Gist options
  • Save mose/6534179 to your computer and use it in GitHub Desktop.
Save mose/6534179 to your computer and use it in GitHub Desktop.
just a tutorial followup
package main
import (
//"fmt"
"net/http"
"io/ioutil"
"html/template"
"regexp"
"errors"
"log"
)
const pagePath = "pages"
const viewPath = "/view/"
const viewLen = len(viewPath)
const editPath = "/edit/"
const editLen = len(editPath)
const savePath = "/save/"
const saveLen = len(savePath)
var templates = template.Must(template.ParseFiles("templates/edit.html", "templates/view.html"))
var nameValidator = regexp.MustCompile("^[-_a-zA-Z0-9]+$")
type Page struct {
Title string
Name string
Body []byte
}
func (p *Page) save() error {
filename := pagePath + "/" + p.Name + ".txt"
return ioutil.WriteFile(filename, p.Body, 0600)
}
func loadPage(name string) (*Page, error) {
filename := pagePath + "/" + name + ".txt"
body, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return &Page{Name: name, Body: body}, nil
}
func getName(w http.ResponseWriter, r *http.Request, lenPath int) (name string, err error) {
name = r.URL.Path[lenPath:]
if !nameValidator.MatchString(name) {
http.NotFound(w, r)
err = errors.New("Invalid Page Name")
}
return
}
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)
}
log.Printf("Page %s delivered.", p.Name)
}
func viewHandler(w http.ResponseWriter, r *http.Request) {
name, err := getName(w, r, viewLen)
if err != nil {
return
}
p, err := loadPage(name)
if err != nil {
http.Redirect(w, r, "/edit/" + name, http.StatusFound)
return
}
renderTemplate(w, "view", p)
}
func editHandler(w http.ResponseWriter, r *http.Request) {
name, err := getName(w, r, editLen)
if err != nil {
return
}
p, err := loadPage(name)
if err != nil {
p = &Page{Name: name}
}
renderTemplate(w, "edit", p)
}
func saveHandler(w http.ResponseWriter, r *http.Request) {
name, err := getName(w, r, saveLen)
if err != nil {
return
}
body := r.FormValue("body")
p := &Page{Name: name, Body: []byte(body)}
err = p.save()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/view/" + name, http.StatusFound)
}
func main() {
http.HandleFunc(viewPath, viewHandler)
http.HandleFunc(editPath, editHandler)
http.HandleFunc(savePath, saveHandler)
http.ListenAndServe(":8080", nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment