diff --git a/caddyhugo.go b/caddyhugo.go index da45969..fe7b71f 100644 --- a/caddyhugo.go +++ b/caddyhugo.go @@ -4,13 +4,13 @@ import ( "errors" "fmt" "html/template" - "io/ioutil" "net/http" "os" "path" "path/filepath" "strings" + "github.com/gorilla/websocket" "github.com/mholt/caddy" "github.com/mholt/caddy/caddyhttp/httpserver" ) @@ -29,20 +29,14 @@ func init() { type CaddyHugo struct { ServerType string + Site *httpserver.SiteConfig authorTmpl, adminTmpl, editTmpl *template.Template } -func (c CaddyHugo) Name() string { - if c.ServerType == "" { - return "hugo" - } - return c.ServerType -} - func (ch CaddyHugo) Setup(c *caddy.Controller) error { - site := httpserver.GetConfig(c) + ch.Site = httpserver.GetConfig(c) var err error @@ -63,12 +57,12 @@ func (ch CaddyHugo) Setup(c *caddy.Controller) error { // add a function that wraps listeners for the HTTP server // (it's more common for a directive to call this rather than a standalone plugin) - site.AddMiddleware(ch.Middleware(c, site)) + ch.Site.AddMiddleware(ch.Middleware(c)) return nil } -func (ch CaddyHugo) Middleware(c *caddy.Controller, site *httpserver.SiteConfig) httpserver.Middleware { +func (ch CaddyHugo) Middleware(c *caddy.Controller) httpserver.Middleware { return func(h httpserver.Handler) httpserver.Handler { return httpserver.HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) { if !ch.Match(r) { @@ -80,13 +74,13 @@ func (ch CaddyHugo) Middleware(c *caddy.Controller, site *httpserver.SiteConfig) } if strings.HasPrefix(r.URL.Path, "/hugo/admin") { - return ch.Admin(site).ServeHTTP(w, r) + return ch.Admin().ServeHTTP(w, r) } if strings.HasPrefix(r.URL.Path, "/hugo/author") { - return ch.AuthorHome(site).ServeHTTP(w, r) + return ch.AuthorHome().ServeHTTP(w, r) } if strings.HasPrefix(r.URL.Path, "/hugo/edit/") { - return ch.Edit(c, site).ServeHTTP(w, r) + return ch.Edit(c).ServeHTTP(w, r) } return http.StatusNotFound, errors.New("not found") @@ -110,9 +104,9 @@ func (ch CaddyHugo) BasePath() string { return "/hugo" } -func (ch CaddyHugo) Admin(site *httpserver.SiteConfig) httpserver.Handler { +func (ch CaddyHugo) Admin() httpserver.Handler { return httpserver.HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) { - err := ch.adminTmpl.Execute(w, ch.TmplData(r, site)) + err := ch.adminTmpl.Execute(w, ch.TmplData(r)) if err != nil { fmt.Println(err) return http.StatusInternalServerError, err @@ -123,9 +117,9 @@ func (ch CaddyHugo) Admin(site *httpserver.SiteConfig) httpserver.Handler { }) } -func (ch CaddyHugo) AuthorHome(site *httpserver.SiteConfig) httpserver.Handler { +func (ch CaddyHugo) AuthorHome() httpserver.Handler { return httpserver.HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) { - err := ch.authorTmpl.Execute(w, ch.TmplData(r, site)) + err := ch.authorTmpl.Execute(w, ch.TmplData(r)) if err != nil { fmt.Println(err) return http.StatusInternalServerError, err @@ -135,48 +129,16 @@ func (ch CaddyHugo) AuthorHome(site *httpserver.SiteConfig) httpserver.Handler { }) } -func (ch CaddyHugo) Edit(c *caddy.Controller, site *httpserver.SiteConfig) httpserver.Handler { +func (ch CaddyHugo) Edit(c *caddy.Controller) httpserver.Handler { return httpserver.HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) { if r.URL.Path == "/hugo/edit/new" { - - name := r.FormValue("name") - ctype := r.FormValue("type") - - if filepath.Ext(name) != ".md" { - name += ".md" - } - - filename := path.Join(site.Root, "content", ctype, name) - - dir := filepath.Dir(filename) - if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) { - err = os.MkdirAll(dir, 0755) - if err != nil { - fmt.Println(err) - return http.StatusInternalServerError, err - } - } - - // create content - f, err := os.Create(filename) - if err != nil && !os.IsExist(err) { - fmt.Println(err) - return http.StatusInternalServerError, err - } - - // we only needed to make the file though - err = f.Close() - if err != nil { - fmt.Println(err) - return http.StatusInternalServerError, err - } - - // serve redirect - http.Redirect(w, r, filepath.Join("/hugo/edit/", filename), http.StatusFound) - return http.StatusFound, nil + return ch.NewContent(w, r) + } + if r.URL.Path == "/hugo/edit/websocket" { + return ch.DeltaWebsocket(w, r) } - err := ch.editTmpl.Execute(w, ch.TmplData(r, site)) + err := ch.editTmpl.Execute(w, ch.TmplData(r)) if err != nil { fmt.Println(err) @@ -187,121 +149,66 @@ func (ch CaddyHugo) Edit(c *caddy.Controller, site *httpserver.SiteConfig) https }) } -func (t tmplData) Content() ([]string, error) { - var files []string - - err := filepath.Walk(path.Join(t.Site.Root, "content"), func(name string, fi os.FileInfo, err error) error { - if fi.IsDir() { - return nil - } - - files = append(files, name) - return nil - }) +func (ch CaddyHugo) DeltaWebsocket(w http.ResponseWriter, r *http.Request) (int, error) { + var upgrader = websocket.Upgrader{ + ReadBufferSize: 1024, + WriteBufferSize: 1024, + } + conn, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Println(err) - return nil, err + return http.StatusBadRequest, err } - return files, nil -} + for { + messageType, p, err := conn.ReadMessage() + if err != nil { + return http.StatusBadRequest, err + } -func (ch CaddyHugo) TmplData(r *http.Request, site *httpserver.SiteConfig) interface{} { - return tmplData{site, r, ch} + fmt.Println(messageType, string(p)) + } } -func (t tmplData) ContentTypes() ([]string, error) { - layoutDir, err := os.Open(path.Join(t.Site.Root, "archetypes")) - if err != nil { - fmt.Println("opening layout dir", err) - return nil, err - } - defer layoutDir.Close() +func (ch CaddyHugo) NewContent(w http.ResponseWriter, r *http.Request) (int, error) { + name := r.FormValue("name") + ctype := r.FormValue("type") - names, err := layoutDir.Readdirnames(0) - if err != nil { - fmt.Println("reading dir", err) - return nil, err + if filepath.Ext(name) != ".md" { + name += ".md" } - out := []string{"default"} - for _, name := range names { - out = append(out, name[:len(name)-len(filepath.Ext(name))]) - } + filename := path.Join(ch.Site.Root, "content", ctype, name) - return out, nil -} + dir := filepath.Dir(filename) + if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) { + err = os.MkdirAll(dir, 0755) + if err != nil { + fmt.Println(err) + return http.StatusInternalServerError, err + } + } -type tmplData struct { - Site *httpserver.SiteConfig - R *http.Request - CaddyHugo -} + // create content + f, err := os.Create(filename) + if err != nil && !os.IsExist(err) { + fmt.Println(err) + return http.StatusInternalServerError, err + } -func (t tmplData) LoadContent() (string, error) { - path := t.R.URL.Path[len("/hugo/edit/"):] - f, err := os.Open(path) + // we only needed to make the file though + err = f.Close() if err != nil { fmt.Println(err) - return "", err + return http.StatusInternalServerError, err } - out, err := ioutil.ReadAll(f) - return string(out), err + + // serve redirect + http.Redirect(w, r, filepath.Join("/hugo/edit/", filename), http.StatusFound) + return http.StatusFound, nil } -var EditPage = ` - - - - - - - - - -
{{ .LoadContent }}
- - -` - -var AdminPage = `not implemented` - -var AuthorPage = ` - - - -

Create content:

-
- - - -
- -

Edit content:

- - -` diff --git a/templates.go b/templates.go new file mode 100644 index 0000000..1f67d16 --- /dev/null +++ b/templates.go @@ -0,0 +1,136 @@ +package caddyhugo + +import ( + "fmt" + "io/ioutil" + "net/http" + "os" + "path" + "path/filepath" + + "github.com/mholt/caddy/caddyhttp/httpserver" +) + +func (t tmplData) Content() ([]string, error) { + var files []string + + err := filepath.Walk(path.Join(t.Site.Root, "content"), func(name string, fi os.FileInfo, err error) error { + if fi.IsDir() { + return nil + } + + files = append(files, name) + return nil + }) + + if err != nil { + fmt.Println(err) + return nil, err + } + + return files, nil +} + +func (t tmplData) ContentTypes() ([]string, error) { + layoutDir, err := os.Open(path.Join(t.Site.Root, "archetypes")) + if err != nil { + fmt.Println("opening layout dir", err) + return nil, err + } + defer layoutDir.Close() + + names, err := layoutDir.Readdirnames(0) + if err != nil { + fmt.Println("reading dir", err) + return nil, err + } + + out := []string{"default"} + for _, name := range names { + out = append(out, name[:len(name)-len(filepath.Ext(name))]) + } + + return out, nil +} + +type tmplData struct { + Site *httpserver.SiteConfig + R *http.Request + CaddyHugo +} + +func (t tmplData) LoadContent() (string, error) { + path := t.R.URL.Path[len("/hugo/edit/"):] + f, err := os.Open(path) + if err != nil { + fmt.Println(err) + return "", err + } + out, err := ioutil.ReadAll(f) + return string(out), err +} + +var EditPage = ` + + + + + + + + + +
{{ .LoadContent }}
+ + +` + +var AdminPage = `not implemented` + +var AuthorPage = ` + + + +

Create content:

+
+ + + +
+ +

Edit content:

+ + +` diff --git a/testdir/testsite/content/.md b/testdir/testsite/content/.md new file mode 100644 index 0000000..e69de29