diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d2f68fe --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +galley +data diff --git a/galley.go b/galley.go index 6de2db2..86d7259 100644 --- a/galley.go +++ b/galley.go @@ -1,32 +1,86 @@ package main import ( - "fmt" + "html/template" + "log" + "net/http" "os" + "regexp" ) +// cache templates on initialization +var templates = template.Must(template.ParseFiles("tmpl/edit.html", "tmpl/view.html")) + +var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$") + func main() { - p1 := &Page{Title: "TestPage", Body: []byte("This is a sample page.")} - p1.save() - p2, _ := loadPage("TestPage") - fmt.Println(string(p2.Body)) + http.HandleFunc("/view/", makeHandler(viewHandler)) + http.HandleFunc("/edit/", makeHandler(editHandler)) + http.HandleFunc("/save/", makeHandler(saveHandler)) + log.Fatal(http.ListenAndServe(":8080", nil)) } type Page struct { Title string - Body []byte + Body []byte } func (p *Page) save() error { - filename := p.Title + ".txt" + filename := "data/" + p.Title + ".txt" return os.WriteFile(filename, p.Body, 0600) } func loadPage(title string) (*Page, error) { - filename := title + ".txt" + filename := "data/" + title + ".txt" body, err := os.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) + } + http.Redirect(w, r, "/view/"+title, http.StatusFound) +} + +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) + } +} + +// function that takes in and modifies a function +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]) + } +} diff --git a/tmpl/edit.html b/tmpl/edit.html new file mode 100644 index 0000000..044c3be --- /dev/null +++ b/tmpl/edit.html @@ -0,0 +1,6 @@ +
[edit]
+