fix #2
This commit is contained in:
parent
3c0383d500
commit
0ac1f84f60
10
README.md
10
README.md
|
@ -2,6 +2,16 @@
|
|||
|
||||
This is an add-on for Caddy which wants to deliver a good UI to edit the content of the website.
|
||||
|
||||
## Add-on configuration
|
||||
|
||||
You can define, or not, the admin UI styles. It will **not** replace the default ones, it will be included after it. The path must be relative to ```public``` folder.
|
||||
|
||||
```
|
||||
hugo {
|
||||
styles [file]
|
||||
}
|
||||
```
|
||||
|
||||
## Try it
|
||||
|
||||
### Prepare your machine
|
||||
|
|
|
@ -6,27 +6,25 @@ import (
|
|||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/hacdias/caddy-hugo/editor"
|
||||
"github.com/hacdias/caddy-hugo/config"
|
||||
"github.com/hacdias/caddy-hugo/utils"
|
||||
"github.com/mholt/caddy/middleware"
|
||||
"github.com/mholt/caddy/middleware/browse"
|
||||
)
|
||||
|
||||
// ServeHTTP is...
|
||||
func ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
if r.URL.Path[len(r.URL.Path)-1] != '/' {
|
||||
http.Redirect(w, r, r.URL.Path+"/", http.StatusTemporaryRedirect)
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
// ServeHTTP is used to serve the content of Browse page
|
||||
// using Browse middleware from Caddy
|
||||
func ServeHTTP(w http.ResponseWriter, r *http.Request, c *config.Config) (int, error) {
|
||||
// Removes the page main path from the URL
|
||||
r.URL.Path = strings.Replace(r.URL.Path, "/admin/browse", "", 1)
|
||||
|
||||
// If the URL is blank now, replace it with a trailing slash
|
||||
if r.URL.Path == "" {
|
||||
r.URL.Path = "/"
|
||||
}
|
||||
|
||||
functions := template.FuncMap{
|
||||
"canBeEdited": editor.CanBeEdited,
|
||||
"CanBeEdited": utils.CanBeEdited,
|
||||
"Defined": utils.Defined,
|
||||
}
|
||||
|
||||
|
@ -45,6 +43,7 @@ func ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
|||
Configs: []browse.Config{
|
||||
browse.Config{
|
||||
PathScope: "/",
|
||||
Variables: c,
|
||||
Template: tpl,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/mholt/caddy/config/setup"
|
||||
)
|
||||
|
||||
// Config is the add-on configuration set on Caddyfile
|
||||
type Config struct {
|
||||
Styles string
|
||||
}
|
||||
|
||||
// ParseHugo parses the configuration file
|
||||
func ParseHugo(c *setup.Controller) (*Config, error) {
|
||||
conf := &Config{}
|
||||
|
||||
for c.Next() {
|
||||
for c.NextBlock() {
|
||||
switch c.Val() {
|
||||
case "styles":
|
||||
if !c.NextArg() {
|
||||
return nil, c.ArgErr()
|
||||
}
|
||||
conf.Styles = c.Val()
|
||||
// Remove the beginning slash if it exists or not
|
||||
conf.Styles = strings.TrimPrefix(conf.Styles, "/")
|
||||
// Add a beginning slash to make a
|
||||
conf.Styles = "/" + conf.Styles
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return conf, nil
|
||||
}
|
|
@ -12,6 +12,7 @@ import (
|
|||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/hacdias/caddy-hugo/config"
|
||||
"github.com/hacdias/caddy-hugo/frontmatter"
|
||||
"github.com/hacdias/caddy-hugo/utils"
|
||||
"github.com/spf13/hugo/parser"
|
||||
|
@ -23,38 +24,21 @@ type editor struct {
|
|||
Mode string
|
||||
Content string
|
||||
FrontMatter interface{}
|
||||
Config *config.Config
|
||||
}
|
||||
|
||||
// ServeHTTP is...
|
||||
func ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
// ServeHTTP serves the editor page
|
||||
func ServeHTTP(w http.ResponseWriter, r *http.Request, c *config.Config) (int, error) {
|
||||
filename := strings.Replace(r.URL.Path, "/admin/edit/", "", 1)
|
||||
|
||||
if r.Method == "POST" {
|
||||
return post(w, r, filename)
|
||||
return servePost(w, r, filename)
|
||||
}
|
||||
|
||||
return get(w, r, filename)
|
||||
return serveGet(w, r, c, filename)
|
||||
}
|
||||
|
||||
// CanBeEdited checks if a file has a supported extension
|
||||
func CanBeEdited(filename string) bool {
|
||||
extensions := [...]string{".markdown", ".md",
|
||||
".json", ".toml", ".yaml",
|
||||
".css", ".sass", ".scss",
|
||||
".js",
|
||||
".html",
|
||||
}
|
||||
|
||||
for _, extension := range extensions {
|
||||
if strings.HasSuffix(filename, extension) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func post(w http.ResponseWriter, r *http.Request, filename string) (int, error) {
|
||||
func servePost(w http.ResponseWriter, r *http.Request, filename string) (int, error) {
|
||||
// Get the JSON information sent using a buffer
|
||||
rawBuffer := new(bytes.Buffer)
|
||||
rawBuffer.ReadFrom(r.Body)
|
||||
|
@ -152,10 +136,10 @@ func post(w http.ResponseWriter, r *http.Request, filename string) (int, error)
|
|||
return 200, nil
|
||||
}
|
||||
|
||||
func get(w http.ResponseWriter, r *http.Request, filename string) (int, error) {
|
||||
func serveGet(w http.ResponseWriter, r *http.Request, c *config.Config, filename string) (int, error) {
|
||||
// Check if the file format is supported. If not, send a "Not Acceptable"
|
||||
// header and an error
|
||||
if !CanBeEdited(filename) {
|
||||
if !utils.CanBeEdited(filename) {
|
||||
return 406, errors.New("File format not supported.")
|
||||
}
|
||||
|
||||
|
@ -176,6 +160,7 @@ func get(w http.ResponseWriter, r *http.Request, filename string) (int, error) {
|
|||
page := new(editor)
|
||||
page.Mode = strings.TrimPrefix(filepath.Ext(filename), ".")
|
||||
page.Name = filename
|
||||
page.Config = c
|
||||
|
||||
// Sanitize the extension
|
||||
page.Mode = sanitizeMode(page.Mode)
|
||||
|
@ -227,7 +212,7 @@ func get(w http.ResponseWriter, r *http.Request, filename string) (int, error) {
|
|||
// Create the functions map, then the template, check for erros and
|
||||
// execute the template if there aren't errors
|
||||
functions := template.FuncMap{
|
||||
"splitCapitalize": utils.SplitCapitalize,
|
||||
"SplitCapitalize": utils.SplitCapitalize,
|
||||
"Defined": utils.Defined,
|
||||
}
|
||||
|
||||
|
|
16
hugo.go
16
hugo.go
|
@ -11,6 +11,7 @@ import (
|
|||
|
||||
"github.com/hacdias/caddy-hugo/assets"
|
||||
"github.com/hacdias/caddy-hugo/browse"
|
||||
"github.com/hacdias/caddy-hugo/config"
|
||||
"github.com/hacdias/caddy-hugo/editor"
|
||||
"github.com/hacdias/caddy-hugo/utils"
|
||||
"github.com/mholt/caddy/config/setup"
|
||||
|
@ -20,16 +21,21 @@ import (
|
|||
|
||||
// Setup configures the middleware
|
||||
func Setup(c *setup.Controller) (middleware.Middleware, error) {
|
||||
config, _ := config.ParseHugo(c)
|
||||
commands.Execute()
|
||||
|
||||
return func(next middleware.Handler) middleware.Handler {
|
||||
return &handler{Next: next}
|
||||
return &CaddyHugo{Next: next, Config: config}
|
||||
}, nil
|
||||
}
|
||||
|
||||
type handler struct{ Next middleware.Handler }
|
||||
// CaddyHugo main type
|
||||
type CaddyHugo struct {
|
||||
Next middleware.Handler
|
||||
Config *config.Config
|
||||
}
|
||||
|
||||
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
func (h CaddyHugo) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
// Only handle /admin path
|
||||
if middleware.Path(r.URL.Path).Matches("/admin") {
|
||||
var err error
|
||||
|
@ -103,12 +109,12 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
|
|||
|
||||
// Browse page
|
||||
if page == "browse" {
|
||||
code, err = browse.ServeHTTP(w, r)
|
||||
code, err = browse.ServeHTTP(w, r, h.Config)
|
||||
}
|
||||
|
||||
// Edit page
|
||||
if page == "edit" {
|
||||
code, err = editor.ServeHTTP(w, r)
|
||||
code, err = editor.ServeHTTP(w, r, h.Config)
|
||||
}
|
||||
|
||||
// Whenever the header "X-Refenerate" is true, the website should be
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
<link href='https://fonts.googleapis.com/css?family=Roboto:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
|
||||
<link rel="stylesheet" href="/admin/assets/css/main.min.css">
|
||||
{{ if and (Defined . "Config")}}{{ if not (eq .Config.Styles "") }}<link rel="stylesheet" href="{{ .Config.Styles }}">{{ end }}{{ end }}
|
||||
{{ if and (Defined . "User") }}{{ if not (eq .User.Styles "") }}<link rel="stylesheet" href="{{ .User.Styles }}">{{ end }}{{ end }}
|
||||
<script src="/admin/assets/js/plugins.min.js"></script>
|
||||
<script src="/admin/assets/js/app.min.js"></script>
|
||||
</head>
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
<tr>
|
||||
<td>
|
||||
{{if .IsDir}}
|
||||
<i class="fa fa-folder"></i> <a href="{{.URL}}">{{.Name}}</a> {{else}} {{ if canBeEdited .URL }}
|
||||
<i class="fa fa-folder"></i> <a href="{{.URL}}">{{.Name}}</a> {{else}} {{ if CanBeEdited .URL }}
|
||||
<i class="fa fa-file"></i> <a class="file" href="/admin/edit{{ $path }}{{.URL}}">{{.Name}}</a> {{ else }}
|
||||
<i class="fa fa-file"></i> {{.Name}} {{ end }} {{ end }}
|
||||
</td>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{{ define "frontmatter" }} {{ range $key, $value := . }} {{ if or (eq $value.Type "object") (eq $value.Type "array") }}
|
||||
<fieldset id="{{ $value.Name }}" data-name="{{ $value.Name }}" data-type="{{ $value.Type }}">
|
||||
<h3>{{ splitCapitalize $value.Title }}
|
||||
<h3>{{ SplitCapitalize $value.Title }}
|
||||
<span class="actions">
|
||||
<button class="delete"><i class="fa fa-minus"></i></button>
|
||||
<button class="add"><i class="fa fa-plus"></i></button>
|
||||
|
@ -9,7 +9,7 @@
|
|||
{{ template "frontmatter" $value.Content }}
|
||||
</fieldset>
|
||||
{{ else }} {{ if not (eq $value.Parent.Type "array") }}
|
||||
<label for="{{ $value.Name }}">{{ splitCapitalize $value.Title }}
|
||||
<label for="{{ $value.Name }}">{{ SplitCapitalize $value.Title }}
|
||||
<span class="actions">
|
||||
<button class="delete"><i class="fa fa-minus"></i></button>
|
||||
</span>
|
||||
|
|
|
@ -12,6 +12,24 @@ import (
|
|||
"github.com/hacdias/caddy-hugo/assets"
|
||||
)
|
||||
|
||||
// CanBeEdited checks if a filename has a supported extension
|
||||
func CanBeEdited(filename string) bool {
|
||||
extensions := [...]string{".markdown", ".md",
|
||||
".json", ".toml", ".yaml",
|
||||
".css", ".sass", ".scss",
|
||||
".js",
|
||||
".html",
|
||||
}
|
||||
|
||||
for _, extension := range extensions {
|
||||
if strings.HasSuffix(filename, extension) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// GetTemplate is used to get a ready to use template based on the url and on
|
||||
// other sent templates
|
||||
func GetTemplate(r *http.Request, functions template.FuncMap, templates ...string) (*template.Template, error) {
|
||||
|
|
Loading…
Reference in New Issue