Hugo preview mode. Update Plugin registration.

pull/194/head
Henrique Dias 2017-08-08 10:21:25 +01:00
parent a2ed744f24
commit ae8eaf96c4
No known key found for this signature in database
GPG Key ID: 936F5EB68D786730
6 changed files with 79 additions and 18 deletions

View File

@ -139,6 +139,7 @@ func parse(c *caddy.Controller) ([]*config, error) {
} }
fm, err := New(database, User{ fm, err := New(database, User{
Locale: "en",
AllowCommands: true, AllowCommands: true,
AllowEdit: true, AllowEdit: true,
AllowNew: true, AllowNew: true,

View File

@ -108,6 +108,7 @@ func parse(c *caddy.Controller) ([]*filemanager.FileManager, error) {
} }
m, err := filemanager.New(database, filemanager.User{ m, err := filemanager.New(database, filemanager.User{
Locale: "en",
AllowCommands: true, AllowCommands: true,
AllowEdit: true, AllowEdit: true,
AllowNew: true, AllowNew: true,

View File

@ -175,6 +175,8 @@ type Rule struct {
Regexp *Regexp `json:"regexp"` Regexp *Regexp `json:"regexp"`
} }
type PluginHandler func(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error)
// Regexp is a regular expression wrapper around native regexp. // Regexp is a regular expression wrapper around native regexp.
type Regexp struct { type Regexp struct {
Raw string `json:"raw"` Raw string `json:"raw"`
@ -185,8 +187,10 @@ type Plugin struct {
JavaScript string JavaScript string
CommandEvents []string CommandEvents []string
Permissions []Permission Permissions []Permission
Handler PluginHandler
Options interface{} Options interface{}
Handlers map[string]PluginHandler `json:"-"`
BeforeAPI PluginHandler `json:"-"`
AfterAPI PluginHandler `json:"-"`
} }
type Permission struct { type Permission struct {
@ -194,13 +198,6 @@ type Permission struct {
Value bool Value bool
} }
type PluginHandler interface {
// If the Plugin returns (0, nil), the executation of File Manager will procced as usual.
// Otherwise it will stop.
Before(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error)
After(c *RequestContext, w http.ResponseWriter, r *http.Request) (int, error)
}
func RegisterPlugin(name string, plugin Plugin) { func RegisterPlugin(name string, plugin Plugin) {
if _, ok := plugins[name]; ok { if _, ok := plugins[name]; ok {
panic(name + " plugin is already registred") panic(name + " plugin is already registred")

36
http.go
View File

@ -58,6 +58,30 @@ func serveHTTP(c *RequestContext, w http.ResponseWriter, r *http.Request) (int,
return apiHandler(c, w, r) return apiHandler(c, w, r)
} }
// Checks if any plugin has an handler for this URL.
for p := range c.Plugins {
var h PluginHandler
for path, handler := range plugins[p].Handlers {
if strings.HasPrefix(r.URL.Path, path) {
h = handler
r.URL.Path = strings.TrimPrefix(r.URL.Path, path)
break
}
}
if h == nil {
continue
}
valid, _ := validateAuth(c, r)
if !valid {
return http.StatusForbidden, nil
}
return h(c, w, r)
}
// Any other request should show the index.html file. // Any other request should show the index.html file.
w.Header().Set("x-frame-options", "SAMEORIGIN") w.Header().Set("x-frame-options", "SAMEORIGIN")
w.Header().Set("x-content-type", "nosniff") w.Header().Set("x-content-type", "nosniff")
@ -108,7 +132,11 @@ func apiHandler(c *RequestContext, w http.ResponseWriter, r *http.Request) (int,
} }
for p := range c.Plugins { for p := range c.Plugins {
code, err := plugins[p].Handler.Before(c, w, r) if plugins[p].BeforeAPI == nil {
continue
}
code, err := plugins[p].BeforeAPI(c, w, r)
if code != 0 || err != nil { if code != 0 || err != nil {
return code, err return code, err
} }
@ -149,7 +177,11 @@ func apiHandler(c *RequestContext, w http.ResponseWriter, r *http.Request) (int,
} }
for p := range c.Plugins { for p := range c.Plugins {
code, err := plugins[p].Handler.After(c, w, r) if plugins[p].AfterAPI == nil {
continue
}
code, err := plugins[p].AfterAPI(c, w, r)
if code != 0 || err != nil { if code != 0 || err != nil {
return code, err return code, err
} }

View File

@ -2,6 +2,7 @@ package plugins
import ( import (
"errors" "errors"
"io/ioutil"
"log" "log"
"net/http" "net/http"
"os" "os"
@ -19,13 +20,16 @@ func init() {
filemanager.RegisterPlugin("hugo", filemanager.Plugin{ filemanager.RegisterPlugin("hugo", filemanager.Plugin{
JavaScript: hugoJavaScript, JavaScript: hugoJavaScript,
CommandEvents: []string{"before_publish", "after_publish"}, CommandEvents: []string{"before_publish", "after_publish"},
BeforeAPI: beforeAPI,
Handlers: map[string]filemanager.PluginHandler{
"/preview": previewHandler,
},
Permissions: []filemanager.Permission{ Permissions: []filemanager.Permission{
{ {
Name: "allowPublish", Name: "allowPublish",
Value: true, Value: true,
}, },
}, },
Handler: &hugo{},
}) })
} }
@ -46,6 +50,8 @@ type Hugo struct {
Args []string `name:"Hugo Arguments"` Args []string `name:"Hugo Arguments"`
// Indicates if we should clean public before a new publish. // Indicates if we should clean public before a new publish.
CleanPublic bool `name:"Clean Public"` CleanPublic bool `name:"Clean Public"`
// previewPath is the temporary path for a preview
previewPath string
} }
// Find finds the hugo executable in the path. // Find finds the hugo executable in the path.
@ -114,9 +120,7 @@ func (h Hugo) undraft(file string) error {
return nil return nil
} }
type hugo struct{} func beforeAPI(c *filemanager.RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
func (h hugo) Before(c *filemanager.RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
o := c.Plugins["hugo"].(*Hugo) o := c.Plugins["hugo"].(*Hugo)
// If we are using the 'magic url' for the settings, we should redirect the // If we are using the 'magic url' for the settings, we should redirect the
@ -223,6 +227,32 @@ func (h hugo) Before(c *filemanager.RequestContext, w http.ResponseWriter, r *ht
return http.StatusNotFound, nil return http.StatusNotFound, nil
} }
func (h hugo) After(c *filemanager.RequestContext, w http.ResponseWriter, r *http.Request) (int, error) { func previewHandler(c *filemanager.RequestContext, w http.ResponseWriter, r *http.Request) (int, error) {
h := c.Plugins["hugo"].(*Hugo)
// Get a new temporary path if there is none.
if h.previewPath == "" {
path, err := ioutil.TempDir("", "")
if err != nil {
return http.StatusInternalServerError, err
}
h.previewPath = path
}
// Build the arguments to execute Hugo: change the base URL,
// build the drafts and update the destination.
args := h.Args
args = append(args, "--baseURL", c.RootURL()+"/preview/")
args = append(args, "--buildDrafts")
args = append(args, "--destination", h.previewPath)
// Builds the preview.
if err := Run(h.Exe, args, h.Root); err != nil {
return http.StatusInternalServerError, err
}
// Serves the temporary path with the preview.
http.FileServer(http.Dir(h.previewPath)).ServeHTTP(w, r)
return 0, nil return 0, nil
} }

View File

@ -143,14 +143,14 @@ const hugoJavaScript = `'use strict';
}, },
icon: 'merge_type', icon: 'merge_type',
name: 'Hugo New' name: 'Hugo New'
} /* , },
{ {
click: function (event, data, route) { click: function (event, data, route) {
console.log('evt') window.open(data.store.state.baseURL + '/preview/')
}, },
icon: 'remove_red_eye', icon: 'remove_red_eye',
name: 'Preview' name: 'Preview'
} */ }
], ],
prompts: [ prompts: [
{ {