diff --git a/galley.go b/galley.go index 768addc..fb75610 100644 --- a/galley.go +++ b/galley.go @@ -1,23 +1,16 @@ package main import ( - "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() { http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) - http.HandleFunc("/view/", makeHandler(viewHandler)) - http.HandleFunc("/edit/", makeHandler(editHandler)) - http.HandleFunc("/save/", makeHandler(saveHandler)) + http.HandleFunc("/view/", MakeHandler(ViewHandler)) + http.HandleFunc("/edit/", MakeHandler(EditHandler)) + http.HandleFunc("/save/", MakeHandler(SaveHandler)) log.Fatal(http.ListenAndServe(":8080", nil)) } @@ -39,49 +32,3 @@ func loadPage(title string) (*Page, error) { } 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/galley_http.go b/galley_http.go new file mode 100644 index 0000000..b3f08be --- /dev/null +++ b/galley_http.go @@ -0,0 +1,47 @@ +package main + +import ( + "net/http" + "regexp" +) + +var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$") + +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) +} + +// 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/galley_templates.go b/galley_templates.go new file mode 100644 index 0000000..fbb9ddc --- /dev/null +++ b/galley_templates.go @@ -0,0 +1,52 @@ +package main + +import ( + "fmt" + "html/template" + "log" + "net/http" + "path/filepath" +) + +// cache templates on initialization +var templates map[string]*template.Template + +// Load templates on program initialisation +func init() { + if templates == nil { + templates = make(map[string]*template.Template) + } + + templatesDir := "tmpl/" + + layouts, err := filepath.Glob(templatesDir + "layouts/*.html") + if err != nil { + log.Fatal(err) + } + + includes, err := filepath.Glob(templatesDir + "includes/*.html") + if err != nil { + log.Fatal(err) + } + + // Generate our templates map from our layouts/ and includes/ directories + for _, layout := range layouts { + files := append(includes, layout) + templates[filepath.Base(layout)] = template.Must(template.ParseFiles(files...)) + } +} + +// renderTemplate is a wrapper around template.ExecuteTemplate. +func RenderTemplate(w http.ResponseWriter, name string, p *Page) { + // Ensure the template exists in the map. + tmpl, ok := templates[name+".html"] + if !ok { + http.Error(w, fmt.Errorf("The template %s does not exist.", name).Error(), http.StatusInternalServerError) + } + + w.Header().Set("Content-Type", "text/html; charset=utf-8") + err := tmpl.ExecuteTemplate(w, "base", p) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + } +} diff --git a/tmpl/edit.html b/tmpl/edit.html deleted file mode 100644 index 044c3be..0000000 --- a/tmpl/edit.html +++ /dev/null @@ -1,6 +0,0 @@ -

Editing {{.Title}}

- -
-
-
-
diff --git a/tmpl/includes/base.html b/tmpl/includes/base.html new file mode 100644 index 0000000..425cbb4 --- /dev/null +++ b/tmpl/includes/base.html @@ -0,0 +1,16 @@ +{{ define "base" }} + + + + + + {{ template "head" . }} + {{ template "title" . }} + + + + {{ template "content" . }} + + + +{{ end }} diff --git a/tmpl/layouts/edit.html b/tmpl/layouts/edit.html new file mode 100644 index 0000000..cffdbc9 --- /dev/null +++ b/tmpl/layouts/edit.html @@ -0,0 +1,16 @@ +{{ define "head" }} + +{{ end }} + +{{ define "title" }} + {{.Title}} +{{ end }} + +{{ define "content" }} +

Editing {{.Title}}

+ +
+
+
+
+{{ end }} diff --git a/tmpl/view.html b/tmpl/layouts/view.html similarity index 60% rename from tmpl/view.html rename to tmpl/layouts/view.html index cce29cf..5170aa8 100644 --- a/tmpl/view.html +++ b/tmpl/layouts/view.html @@ -1,14 +1,13 @@ - - - - +{{ define "head" }} - +{{ end }} - +{{ define "title" }} + {{.Title}} +{{ end }} + +{{ define "content" }}

{{.Title}}

[edit]

{{printf "%s" .Body}}
- - - +{{ end }}