update
parent
72c7abe469
commit
0797fde4e3
99
binary.go
99
binary.go
|
@ -7,35 +7,20 @@
|
||||||
package hugo
|
package hugo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"compress/gzip"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func bindataRead(data []byte, name string) ([]byte, error) {
|
// bindataRead reads the given file from disk. It returns an error on failure.
|
||||||
gz, err := gzip.NewReader(bytes.NewBuffer(data))
|
func bindataRead(path, name string) ([]byte, error) {
|
||||||
|
buf, err := ioutil.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
err = fmt.Errorf("Error reading asset %s at %s: %v", name, path, err)
|
||||||
}
|
}
|
||||||
|
return buf, err
|
||||||
var buf bytes.Buffer
|
|
||||||
_, err = io.Copy(&buf, gz)
|
|
||||||
clErr := gz.Close()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("Read %q: %v", name, err)
|
|
||||||
}
|
|
||||||
if clErr != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type asset struct {
|
type asset struct {
|
||||||
|
@ -43,70 +28,40 @@ type asset struct {
|
||||||
info os.FileInfo
|
info os.FileInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
type bindataFileInfo struct {
|
// templatesEditorTmpl reads file data from disk. It returns an error on failure.
|
||||||
name string
|
|
||||||
size int64
|
|
||||||
mode os.FileMode
|
|
||||||
modTime time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fi bindataFileInfo) Name() string {
|
|
||||||
return fi.name
|
|
||||||
}
|
|
||||||
func (fi bindataFileInfo) Size() int64 {
|
|
||||||
return fi.size
|
|
||||||
}
|
|
||||||
func (fi bindataFileInfo) Mode() os.FileMode {
|
|
||||||
return fi.mode
|
|
||||||
}
|
|
||||||
func (fi bindataFileInfo) ModTime() time.Time {
|
|
||||||
return fi.modTime
|
|
||||||
}
|
|
||||||
func (fi bindataFileInfo) IsDir() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
func (fi bindataFileInfo) Sys() interface{} {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var _templatesEditorTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xc4\x56\x4d\x6f\xdc\x38\x0c\xbd\x07\xc8\x7f\xe0\xea\x94\x3d\x8c\x8d\xbd\x7b\xbc\x58\xec\x6e\x8b\x1e\xd2\x0e\x30\x01\x7a\xd6\x58\x9c\x58\x88\x6d\xb9\x12\x3d\xd3\x41\x90\xff\x5e\xca\xf2\x97\x32\xcd\x07\x82\xa0\xf5\xc9\x96\xc8\xc7\x47\xf2\x51\xf2\xfd\x3d\x28\xdc\xeb\x06\x41\x14\xa6\x21\x6c\x48\xc0\xc3\xc3\xe5\x45\xa6\xf4\x01\x8a\x4a\x3a\xb7\x16\xa8\x34\x19\x0b\x7e\x5f\xb2\xa5\x05\x76\x4a\xfe\xf5\x7b\x6c\x2a\xf2\xcb\x0b\xf0\x2b\x7a\x0f\xf8\x6d\x5c\x67\xb0\xba\xad\x90\x30\xa0\x01\x64\xe5\x5f\x79\x46\xf8\x9d\xa4\x45\x09\x5a\xad\x85\xd3\x84\x2b\xd2\x54\xa1\xc8\x3d\xe0\x67\x59\x23\x1b\x67\xe9\x68\x95\x67\x29\x3b\x0d\xe8\xd8\xa8\x11\x69\x6f\x6c\x0d\x35\x52\x69\x18\x65\xf3\x65\x7b\x23\x40\x16\xa4\x4d\xb3\x16\x81\x0c\xdb\xd4\x4c\x74\x78\x1f\xc9\x35\x86\xe0\xea\x67\x0c\xff\x1c\x80\xc3\xc3\x44\x9f\xa7\x37\x70\x1a\x80\x47\x5e\x71\xac\x45\x98\xbd\xe5\xb2\xd5\x92\x08\xed\xca\x34\xd5\x49\x2c\xa2\x2d\x8b\xbc\xb0\x83\x5d\x65\x8a\x3b\x27\xf2\x99\x15\xc3\x12\x32\x5f\x49\x18\x41\x0a\x48\x3e\xf8\xaf\xeb\xe0\x18\x25\xd2\x8e\xd0\xa1\x3a\x11\x1e\x6f\xef\x3a\x22\xd3\x4c\x36\x4a\x89\xfc\x1f\xa5\x60\xaf\xb1\x52\x59\x1a\x76\x17\x1e\x59\xda\x4e\x5f\x59\xca\xc4\xa3\x2a\x54\x0e\xcf\x04\xd0\xab\xe9\xd9\x9c\x47\xc5\x2d\xc3\xf8\x6d\x5f\xff\x20\xba\x95\x33\x9d\x2d\x58\x45\x4a\x92\x5c\xd5\x46\xe1\x5a\xf8\x6e\x5c\xf3\x5b\x2f\xbe\x98\x0a\xfb\x4f\x1a\x6b\xb8\x61\x8b\x10\xbd\x66\xc3\x47\xac\xb2\xe7\x93\x7a\xb1\x59\x67\xe4\x07\x93\xf7\xe9\xe1\xc0\xe9\x97\x76\xf5\x95\x9d\x9a\x95\xde\x37\x43\xd4\xd2\xde\x29\x73\x6c\x44\x9c\x41\x23\x0f\x31\xc3\x61\xfa\x11\xa7\xde\x2e\x12\x3a\xf0\xb4\x65\x7a\x2a\xb3\x84\xbd\x5c\x15\x0c\xef\x1b\xad\x73\xd8\xf6\x1e\x59\x2a\x9f\x82\x6c\x2d\x1e\x34\x1e\xcf\x41\xf0\x34\x62\x6c\x82\x49\x0c\x92\xa5\x31\xcf\x30\xd9\x51\x22\xbf\x4d\x98\xe7\xb1\xe7\x2c\xa3\x20\xe7\x0a\x7e\x74\x38\xcd\xe2\x21\x63\xaa\x9d\x8c\xc5\xab\x9b\xb6\x23\xa0\x53\xcb\xec\x5c\xb7\xab\x35\x0d\xd9\x85\xa5\xe8\xd0\x0f\x1b\x16\x6f\x91\xef\x03\x16\xb4\x2f\x33\x8f\xcb\xb0\xee\x8a\x12\x55\x57\xcd\xab\x43\x95\xd0\x39\x79\x1b\xa0\x5e\x3e\x24\x6f\x4a\x0c\xb2\x75\x70\x44\x8b\xe0\xc9\xb1\xb2\xa9\x44\x6d\xe1\x28\x4f\xc9\xeb\xce\x9d\xff\x0f\x68\x4f\xb0\x3b\xf1\xd0\x1d\xa5\x03\x27\x0f\xa8\x92\x79\xba\x37\xc6\x51\x58\x84\xa3\xa6\x12\x5a\xbe\x15\x40\x72\xdd\x0a\x6d\x8b\xae\x76\x24\x9b\x02\x93\xa9\x96\x02\x0e\xb2\xea\x38\x85\xad\xf4\x52\x5d\x54\xcf\xb5\x72\x1a\x3b\xab\x6f\x4b\x8a\x07\x33\xa4\xec\x81\x9f\xb8\x83\xae\x20\xf9\xe4\x7a\x36\xfe\x3e\x7a\x43\x33\xe6\xa2\x93\xed\xf0\x85\x0e\x4d\xad\x08\xf9\x0f\xae\x2a\xe1\x56\x8d\x09\x0e\x6b\x22\x8f\xaf\xdf\x77\x92\xcb\x82\xe3\x99\x5a\xde\x20\x96\x6d\xdf\x41\x5f\xde\x39\x88\x7a\xa5\x42\xfe\x33\x0d\x26\xf0\xb5\x94\x04\xca\xc0\xc9\x74\x2c\x14\x9e\xc5\xda\x58\xfc\xfb\x91\x50\xda\x6e\x57\x69\xc7\x74\x13\xf8\x68\xfa\x70\xae\xe4\x59\x05\x4d\x7f\x2c\x24\x32\xa8\x80\xff\xab\x64\x57\xd1\x24\x99\x4d\x70\x8e\x54\x93\x7a\xd9\x2c\x06\x78\x3c\x8d\xb3\x74\xfa\x83\xc9\x52\xff\xc3\xc3\xaf\xe3\x78\x2f\xda\xf1\x23\x00\x00\xff\xff\x32\x91\x30\x45\xbe\x09\x00\x00")
|
|
||||||
|
|
||||||
func templatesEditorTmplBytes() ([]byte, error) {
|
|
||||||
return bindataRead(
|
|
||||||
_templatesEditorTmpl,
|
|
||||||
"templates/editor.tmpl",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func templatesEditorTmpl() (*asset, error) {
|
func templatesEditorTmpl() (*asset, error) {
|
||||||
bytes, err := templatesEditorTmplBytes()
|
path := "D:\\Code\\Go\\src\\github.com\\hacdias\\caddy-hugo\\assets\\templates\\editor.tmpl"
|
||||||
|
name := "templates/editor.tmpl"
|
||||||
|
bytes, err := bindataRead(path, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "templates/editor.tmpl", size: 2494, mode: os.FileMode(438), modTime: time.Unix(1466520293, 0)}
|
fi, err := os.Stat(path)
|
||||||
a := &asset{bytes: bytes, info: info}
|
if err != nil {
|
||||||
return a, nil
|
err = fmt.Errorf("Error reading asset info %s at %s: %v", name, path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _templatesFrontmatterTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xbc\x54\xdd\x6e\xd3\x4c\x10\xbd\xaf\xd4\x77\x18\xed\x57\x7d\x02\x09\xc7\x69\x5a\x7e\x14\x1c\xdf\x54\x42\x5c\x00\x42\x22\x2f\xb0\xb1\xc7\xb0\x74\xb3\x6b\xd6\x93\x8a\x50\xf5\xdd\x19\xaf\xbd\xa9\xb1\x9d\xca\xad\x10\x77\x59\x9f\xd9\xd9\x73\xce\xcc\xc9\xed\x2d\xe4\x58\x28\x83\x20\x0a\x67\x0d\x6d\x25\x11\x3a\x01\x77\x77\xa7\x27\x8c\x39\x69\xbe\x22\x9c\x5d\xe3\xfe\x05\x9c\xdd\x48\xbd\x43\x58\xae\x60\xe6\xe1\xd3\x13\x00\x2e\x51\x05\x58\x07\xcf\xf0\x47\x5b\x30\x5b\xef\x4b\xee\x66\x37\xdf\x31\x23\xf1\x7c\x88\x48\xe7\xe4\x9e\x81\xba\x07\x40\x52\x28\xd4\x79\x85\x04\x2a\x5f\x09\xee\xd7\xd6\x7e\x92\x5b\xe4\x12\x01\xb9\x24\x19\x11\xdf\xec\xa2\xbe\x13\xa3\x69\xdd\x82\x9b\x7c\xbb\x48\x19\xfc\x52\x6a\x45\x57\xb2\x54\x24\xb5\xfa\x85\x87\x62\x45\xba\xae\x4e\x62\x2e\x6b\x2f\x54\xa5\x34\x90\x69\x59\x55\x2b\x21\x33\x52\xd6\x54\xa1\x19\xa3\x9b\x1d\x91\xbd\xc7\xf3\x5c\xa4\xff\xff\x77\x79\xf1\x36\x89\x1b\xe4\x58\x65\x8e\x1a\x09\xeb\xe2\x37\xaf\x17\x8b\x7e\x79\x12\xd7\xaf\xb6\x07\xa6\x4b\xb8\x2d\xb5\xa4\xbe\xf5\x2d\xeb\x2b\xfe\x84\x86\x82\x4d\x71\xf0\x29\x6d\x7d\x47\x5d\x61\x6f\x0e\xc6\x52\xd7\xee\xcf\xd2\x71\x83\x71\xd7\x73\x75\x13\x48\x6f\xb4\xcd\xae\x85\xb7\xdf\xff\x8c\x8e\x0d\x21\x6b\x18\x8d\x4d\x29\x28\xd4\x72\x83\x1a\x0a\xeb\x46\x8b\xa6\x8c\xc8\x77\x78\xca\x94\x26\x7a\x1f\xdc\x33\x79\xcf\xbc\x07\x7d\xeb\xda\x36\xba\xa7\xde\x34\x8e\x49\x7f\x65\xfd\xf5\x48\xf1\xa8\x45\x3a\xe1\xe9\xf7\xeb\x8f\x1f\x9a\x77\x09\x7f\x12\xf3\x90\x87\xa7\xc3\x87\xa0\xb7\xca\x9c\xd5\x5a\x80\x61\x02\x23\x84\x96\xc3\xb0\x3c\x98\xb0\xd2\x8b\x1e\x04\xad\xeb\x45\x3b\xc2\xc1\x7e\x26\x71\xe0\xf6\xc7\x6e\x1e\x11\xc6\xaf\x21\xa9\x2d\x1e\x84\x29\x53\xee\xe8\x2f\xc8\xf0\xc7\x2e\xd2\x32\x9c\xbd\xb3\x8e\xb3\x05\x62\x31\x9f\xbf\x8a\xe6\xe7\xd1\x7c\xb1\x3e\x7f\xb9\x9c\x5f\x0a\x7f\xad\x51\x1c\x58\x45\x9c\x00\xa9\x1f\xe7\x49\x12\x7b\x09\x83\x60\xfe\x03\x6d\x1d\x05\xf7\xd8\xc1\xeb\xc7\x0e\xb7\x2f\x64\xb0\xa8\xd3\xfe\x60\x92\x98\x63\x92\x3e\x3d\x64\xa3\xa9\x9f\x98\xf6\x36\xe7\x0d\x85\x81\x8e\xce\x61\xfc\xe7\xef\x00\x00\x00\xff\xff\x30\xc2\x3e\x0c\x0f\x07\x00\x00")
|
a := &asset{bytes: bytes, info: fi}
|
||||||
|
return a, err
|
||||||
func templatesFrontmatterTmplBytes() ([]byte, error) {
|
|
||||||
return bindataRead(
|
|
||||||
_templatesFrontmatterTmpl,
|
|
||||||
"templates/frontmatter.tmpl",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// templatesFrontmatterTmpl reads file data from disk. It returns an error on failure.
|
||||||
func templatesFrontmatterTmpl() (*asset, error) {
|
func templatesFrontmatterTmpl() (*asset, error) {
|
||||||
bytes, err := templatesFrontmatterTmplBytes()
|
path := "D:\\Code\\Go\\src\\github.com\\hacdias\\caddy-hugo\\assets\\templates\\frontmatter.tmpl"
|
||||||
|
name := "templates/frontmatter.tmpl"
|
||||||
|
bytes, err := bindataRead(path, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "templates/frontmatter.tmpl", size: 1807, mode: os.FileMode(438), modTime: time.Unix(1466520317, 0)}
|
fi, err := os.Stat(path)
|
||||||
a := &asset{bytes: bytes, info: info}
|
if err != nil {
|
||||||
return a, nil
|
err = fmt.Errorf("Error reading asset info %s at %s: %v", name, path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
a := &asset{bytes: bytes, info: fi}
|
||||||
|
return a, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Asset loads and returns the asset for the given name.
|
// Asset loads and returns the asset for the given name.
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
package files
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CopyFile is used to copy a file
|
|
||||||
func CopyFile(old, new string) error {
|
|
||||||
// Open the file and create a new one
|
|
||||||
r, err := os.Open(old)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer r.Close()
|
|
||||||
|
|
||||||
w, err := os.Create(new)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer w.Close()
|
|
||||||
|
|
||||||
// Copy the content
|
|
||||||
_, err = io.Copy(w, r)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
package files
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestCopyFile(t *testing.T) {
|
|
||||||
err := CopyFile("test_data/file_to_copy.txt", "test_data/copied_file.txt")
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
t.Error("Can't copy the file.")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin faucibus augue vel ex auctor molestie. Sed id lorem quis velit eleifend vestibulum. Etiam tincidunt nulla et metus dictum imperdiet. Suspendisse ac auctor risus. Donec tempus eros quis erat interdum fringilla. Duis ac tristique lorem, quis vulputate enim. In ut est elementum, dignissim tellus quis, ultrices diam. Aenean in efficitur velit, ut imperdiet felis. Suspendisse aliquet accumsan ligula, a iaculis sem luctus vel. Integer sagittis, orci viverra lacinia efficitur, eros magna sodales sapien, in tristique ante arcu ut nunc. Maecenas odio dolor, semper quis vehicula ut, malesuada sollicitudin massa. Integer dolor ligula, hendrerit convallis quam at, luctus dignissim nibh. Fusce interdum congue justo, at imperdiet lorem maximus in.
|
|
||||||
|
|
||||||
Curabitur dignissim id turpis ut eleifend. Pellentesque vehicula et purus et consectetur. Nulla facilisis vehicula nunc in imperdiet. Nam eget porta libero, vel dapibus leo. Maecenas iaculis, arcu quis vehicula sollicitudin, massa tortor mattis tortor, vitae venenatis erat neque et dui. Mauris eleifend vel urna ac interdum. Sed convallis, arcu et scelerisque suscipit, nulla urna laoreet mauris, quis aliquam dolor elit id mauris. Pellentesque ac pulvinar nibh. Duis vestibulum ligula orci, et mattis turpis facilisis mattis. Vivamus feugiat neque sed aliquet aliquet. Sed consequat augue sagittis eros imperdiet, ac lacinia erat tempor. Cras gravida mi a orci euismod feugiat. Mauris condimentum turpis id quam vulputate, et maximus dolor hendrerit.
|
|
||||||
|
|
||||||
Ut nisi urna, sollicitudin ac facilisis eu, rhoncus sed urna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nulla eu maximus mi, sed commodo diam. Nunc scelerisque tincidunt ipsum eget mattis. Fusce id finibus nisi, sit amet tempus tortor. Fusce accumsan lectus at dignissim volutpat. Nullam nisl nulla, rhoncus id arcu vitae, eleifend posuere libero. Aliquam dictum bibendum bibendum. Integer non mattis neque. Phasellus fermentum et ex vel vehicula.
|
|
||||||
|
|
||||||
Proin eget ligula lorem. Ut vehicula quis augue sed aliquet. Nulla viverra turpis nulla. Morbi et ipsum odio. Nulla in nisi suscipit justo blandit tristique ac vitae ipsum. Donec viverra dictum arcu. Duis est elit, ultrices a massa non, lobortis maximus eros. Nulla porttitor rhoncus lectus in finibus. Duis convallis sapien porta, fringilla orci nec, ultricies nisl. Morbi pulvinar quam in nulla rutrum euismod.
|
|
||||||
|
|
||||||
Donec et accumsan lectus, consectetur posuere nunc. Quisque et quam hendrerit, vestibulum quam eget, luctus enim. In hac habitasse platea dictumst. Nunc et est scelerisque, bibendum neque quis, ornare elit. Aliquam erat volutpat. Nulla maximus nibh vitae ex interdum, a efficitur lacus eleifend. Nam vestibulum blandit aliquet. In hac habitasse platea dictumst. Maecenas interdum quam et lorem posuere interdum. Mauris id feugiat augue. Etiam vestibulum pharetra cursus.
|
|
|
@ -23,7 +23,7 @@ type editor struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET handles the GET method on editor page
|
// GET handles the GET method on editor page
|
||||||
func (h Hugo) GET(w http.ResponseWriter, r *http.Request, c *Config, filename string) (int, error) {
|
func (h Hugo) GET(w http.ResponseWriter, r *http.Request, filename string) (int, error) {
|
||||||
// Check if the file exists.
|
// Check if the file exists.
|
||||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||||
return http.StatusNotFound, err
|
return http.StatusNotFound, err
|
||||||
|
@ -45,14 +45,14 @@ func (h Hugo) GET(w http.ResponseWriter, r *http.Request, c *Config, filename st
|
||||||
Info: &filemanager.PageInfo{
|
Info: &filemanager.PageInfo{
|
||||||
IsDir: false,
|
IsDir: false,
|
||||||
Config: &h.FileManager.Configs[0],
|
Config: &h.FileManager.Configs[0],
|
||||||
Name: strings.Replace(filename, c.Root, "", 1),
|
Name: strings.Replace(filename, h.Config.Root, "", 1),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new editor variable and set the extension
|
// Create a new editor variable and set the extension
|
||||||
data := new(editor)
|
data := new(editor)
|
||||||
data.Mode = strings.TrimPrefix(filepath.Ext(filename), ".")
|
data.Mode = strings.TrimPrefix(filepath.Ext(filename), ".")
|
||||||
data.Name = strings.Replace(filename, c.Root, "", 1)
|
data.Name = strings.Replace(filename, h.Config.Root, "", 1)
|
||||||
data.IsPost = false
|
data.IsPost = false
|
||||||
data.Mode = sanitizeMode(data.Mode)
|
data.Mode = sanitizeMode(data.Mode)
|
||||||
|
|
||||||
|
@ -113,15 +113,18 @@ func (h Hugo) GET(w http.ResponseWriter, r *http.Request, c *Config, filename st
|
||||||
var code int
|
var code int
|
||||||
|
|
||||||
page.Info.Data = data
|
page.Info.Data = data
|
||||||
code, err = page.AddTemplate("base", filemanager.Asset, functions)
|
|
||||||
|
|
||||||
if err != nil {
|
templates := []string{"frontmatter", "editor"}
|
||||||
return code, err
|
for _, t := range templates {
|
||||||
|
code, err = page.AddTemplate(t, Asset, functions)
|
||||||
|
if err != nil {
|
||||||
|
return code, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
templates := []string{"listing", "actions"}
|
templates = []string{"actions", "base"}
|
||||||
for _, t := range templates {
|
for _, t := range templates {
|
||||||
code, err = page.AddTemplate(t, Asset, nil)
|
code, err = page.AddTemplate(t, filemanager.Asset, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return code, err
|
return code, err
|
||||||
}
|
}
|
89
hugo.go
89
hugo.go
|
@ -1,6 +1,6 @@
|
||||||
//go:generate go get github.com/jteeuwen/go-bindata
|
//go:generate go get github.com/jteeuwen/go-bindata
|
||||||
//go:generate go install github.com/jteeuwen/go-bindata/go-bindata
|
//go:generate go install github.com/jteeuwen/go-bindata/go-bindata
|
||||||
//go:generate go-bindata -pkg hugo -prefix "assets" -o binary.go assets/...
|
//go:generate go-bindata -debug -pkg hugo -prefix "assets" -o binary.go assets/...
|
||||||
|
|
||||||
// Package hugo makes the bridge between the static website generator Hugo
|
// Package hugo makes the bridge between the static website generator Hugo
|
||||||
// and the webserver Caddy, also providing an administrative user interface.
|
// and the webserver Caddy, also providing an administrative user interface.
|
||||||
|
@ -8,6 +8,9 @@ package hugo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/hacdias/caddy-filemanager"
|
"github.com/hacdias/caddy-filemanager"
|
||||||
"github.com/mholt/caddy/caddyhttp/httpserver"
|
"github.com/mholt/caddy/caddyhttp/httpserver"
|
||||||
|
@ -24,6 +27,90 @@ type Hugo struct {
|
||||||
// ServeHTTP is the main function of the whole plugin that routes every single
|
// ServeHTTP is the main function of the whole plugin that routes every single
|
||||||
// request to its function.
|
// request to its function.
|
||||||
func (h Hugo) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
func (h Hugo) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||||
|
// Check if the current request if for this plugin
|
||||||
|
if httpserver.Path(r.URL.Path).Matches(h.Config.BaseURL) {
|
||||||
|
// If the url matches exactly with /{admin}/settings/, redirect
|
||||||
|
// to the page of the configuration file
|
||||||
|
if r.URL.Path == h.Config.BaseURL+"/settings/" {
|
||||||
|
var frontmatter string
|
||||||
|
|
||||||
|
if _, err := os.Stat(h.Config.Root + "config.yaml"); err == nil {
|
||||||
|
frontmatter = "yaml"
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(h.Config.Root + "config.json"); err == nil {
|
||||||
|
frontmatter = "json"
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(h.Config.Root + "config.toml"); err == nil {
|
||||||
|
frontmatter = "toml"
|
||||||
|
}
|
||||||
|
|
||||||
|
http.Redirect(w, r, h.Config.BaseURL+"/config."+frontmatter, http.StatusTemporaryRedirect)
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(r.URL.Path, h.Config.BaseURL+"/api/git/") && r.Method == http.MethodPost {
|
||||||
|
//return HandleGit(w, r, h.Config)
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if h.ShouldHandle(r) {
|
||||||
|
filename := strings.Replace(r.URL.Path, h.Config.BaseURL, h.Config.Root, 1)
|
||||||
|
switch r.Method {
|
||||||
|
case http.MethodGet:
|
||||||
|
return h.GET(w, r, filename)
|
||||||
|
case http.MethodPost:
|
||||||
|
return h.POST(w, r, filename)
|
||||||
|
default:
|
||||||
|
return h.FileManager.ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.FileManager.ServeHTTP(w, r)
|
||||||
|
}
|
||||||
return h.Next.ServeHTTP(w, r)
|
return h.Next.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var extensions = []string{
|
||||||
|
"md", "markdown", "mdown", "mmark",
|
||||||
|
"asciidoc", "adoc", "ad",
|
||||||
|
"rst",
|
||||||
|
"html", "htm",
|
||||||
|
"js",
|
||||||
|
"toml", "yaml", "json",
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShouldHandle checks if this extension should be handled by this plugin
|
||||||
|
func (h Hugo) ShouldHandle(r *http.Request) bool {
|
||||||
|
// Checks if the method is get or post
|
||||||
|
if r.Method != http.MethodGet && r.Method != http.MethodPost {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this request is for FileManager assets
|
||||||
|
if httpserver.Path(r.URL.Path).Matches(h.Config.BaseURL + filemanager.AssetsURL) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this request requires a raw file or a download, return the FileManager
|
||||||
|
query := r.URL.Query()
|
||||||
|
if val, ok := query["raw"]; ok && val[0] == "true" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, ok := query["download"]; ok && val[0] == "true" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check by file extension
|
||||||
|
extension := strings.TrimPrefix(filepath.Ext(r.URL.Path), ".")
|
||||||
|
|
||||||
|
for _, ext := range extensions {
|
||||||
|
if ext == extension {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/hacdias/caddy-hugo/files"
|
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
"github.com/pivotal-golang/archiver/extractor"
|
"github.com/pivotal-golang/archiver/extractor"
|
||||||
)
|
)
|
||||||
|
@ -91,7 +90,7 @@ func GetPath() string {
|
||||||
|
|
||||||
// Copy the file
|
// Copy the file
|
||||||
fmt.Print("Moving Hugo executable... ")
|
fmt.Print("Moving Hugo executable... ")
|
||||||
err = files.CopyFile(exetorename, hugo)
|
err = CopyFile(exetorename, hugo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
|
@ -214,3 +213,27 @@ func checkSHA256() {
|
||||||
|
|
||||||
fmt.Println("checked!")
|
fmt.Println("checked!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CopyFile is used to copy a file
|
||||||
|
func CopyFile(old, new string) error {
|
||||||
|
// Open the file and create a new one
|
||||||
|
r, err := os.Open(old)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
w, err := os.Create(new)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer w.Close()
|
||||||
|
|
||||||
|
// Copy the content
|
||||||
|
_, err = io.Copy(w, r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,203 @@
|
||||||
|
package hugo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/robfig/cron"
|
||||||
|
"github.com/spf13/cast"
|
||||||
|
"github.com/spf13/hugo/parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
type info struct {
|
||||||
|
ContentType string
|
||||||
|
Schedule bool
|
||||||
|
Regenerate bool
|
||||||
|
Content map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type response struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST handles the POST method on editor page
|
||||||
|
func (h Hugo) POST(w http.ResponseWriter, r *http.Request, filename string) (int, error) {
|
||||||
|
var data info
|
||||||
|
|
||||||
|
// Get the JSON information sent using a buffer
|
||||||
|
rawBuffer := new(bytes.Buffer)
|
||||||
|
rawBuffer.ReadFrom(r.Body)
|
||||||
|
err := json.Unmarshal(rawBuffer.Bytes(), &data)
|
||||||
|
|
||||||
|
fmt.Println(string(rawBuffer.Bytes()))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return RespondJSON(w, &response{"Error decrypting json."}, http.StatusInternalServerError, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initializes the file content to write
|
||||||
|
var file []byte
|
||||||
|
var code int
|
||||||
|
|
||||||
|
switch data.ContentType {
|
||||||
|
case "frontmatter-only":
|
||||||
|
file, code, err = parseFrontMatterOnlyFile(data, filename)
|
||||||
|
if err != nil {
|
||||||
|
return RespondJSON(w, &response{err.Error()}, code, err)
|
||||||
|
}
|
||||||
|
case "content-only":
|
||||||
|
// The main content of the file
|
||||||
|
mainContent := data.Content["content"].(string)
|
||||||
|
mainContent = strings.TrimSpace(mainContent)
|
||||||
|
|
||||||
|
file = []byte(mainContent)
|
||||||
|
case "complete":
|
||||||
|
file, code, err = parseCompleteFile(data, filename, h.Config)
|
||||||
|
if err != nil {
|
||||||
|
return RespondJSON(w, &response{err.Error()}, code, err)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return RespondJSON(w, &response{"Invalid content type."}, http.StatusBadRequest, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the file
|
||||||
|
err = ioutil.WriteFile(filename, file, 0666)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return RespondJSON(w, &response{err.Error()}, http.StatusInternalServerError, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.Regenerate {
|
||||||
|
go RunHugo(h.Config, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return RespondJSON(w, nil, http.StatusOK, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseFrontMatterOnlyFile(data info, filename string) ([]byte, int, error) {
|
||||||
|
frontmatter := strings.TrimPrefix(filepath.Ext(filename), ".")
|
||||||
|
var mark rune
|
||||||
|
|
||||||
|
switch frontmatter {
|
||||||
|
case "toml":
|
||||||
|
mark = rune('+')
|
||||||
|
case "json":
|
||||||
|
mark = rune('{')
|
||||||
|
case "yaml":
|
||||||
|
mark = rune('-')
|
||||||
|
default:
|
||||||
|
return []byte{}, http.StatusBadRequest, errors.New("Can't define the frontmatter.")
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := parser.InterfaceToFrontMatter(data.Content, mark)
|
||||||
|
fString := string(f)
|
||||||
|
|
||||||
|
// If it's toml or yaml, strip frontmatter identifier
|
||||||
|
if frontmatter == "toml" {
|
||||||
|
fString = strings.TrimSuffix(fString, "+++\n")
|
||||||
|
fString = strings.TrimPrefix(fString, "+++\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
if frontmatter == "yaml" {
|
||||||
|
fString = strings.TrimSuffix(fString, "---\n")
|
||||||
|
fString = strings.TrimPrefix(fString, "---\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
f = []byte(fString)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return f, http.StatusOK, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseCompleteFile(data info, filename string, c *Config) ([]byte, int, error) {
|
||||||
|
// The main content of the file
|
||||||
|
mainContent := data.Content["content"].(string)
|
||||||
|
mainContent = "\n\n" + strings.TrimSpace(mainContent) + "\n"
|
||||||
|
|
||||||
|
// Removes the main content from the rest of the frontmatter
|
||||||
|
delete(data.Content, "content")
|
||||||
|
|
||||||
|
if _, ok := data.Content["date"]; ok {
|
||||||
|
data.Content["date"] = data.Content["date"].(string) + ":00"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schedule the post
|
||||||
|
if data.Schedule {
|
||||||
|
t := cast.ToTime(data.Content["date"])
|
||||||
|
|
||||||
|
scheduler := cron.New()
|
||||||
|
scheduler.AddFunc(t.In(time.Now().Location()).Format("05 04 15 02 01 *"), func() {
|
||||||
|
// Set draft to false
|
||||||
|
data.Content["draft"] = false
|
||||||
|
|
||||||
|
// Converts the frontmatter in JSON
|
||||||
|
jsonFrontmatter, err := json.Marshal(data.Content)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Indents the json
|
||||||
|
frontMatterBuffer := new(bytes.Buffer)
|
||||||
|
json.Indent(frontMatterBuffer, jsonFrontmatter, "", " ")
|
||||||
|
|
||||||
|
// Generates the final file
|
||||||
|
f := new(bytes.Buffer)
|
||||||
|
f.Write(frontMatterBuffer.Bytes())
|
||||||
|
f.Write([]byte(mainContent))
|
||||||
|
file := f.Bytes()
|
||||||
|
|
||||||
|
// Write the file
|
||||||
|
if err = ioutil.WriteFile(filename, file, 0666); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
go RunHugo(c, false)
|
||||||
|
})
|
||||||
|
scheduler.Start()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts the frontmatter in JSON
|
||||||
|
jsonFrontmatter, err := json.Marshal(data.Content)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Indents the json
|
||||||
|
frontMatterBuffer := new(bytes.Buffer)
|
||||||
|
json.Indent(frontMatterBuffer, jsonFrontmatter, "", " ")
|
||||||
|
|
||||||
|
// Generates the final file
|
||||||
|
f := new(bytes.Buffer)
|
||||||
|
f.Write(frontMatterBuffer.Bytes())
|
||||||
|
f.Write([]byte(mainContent))
|
||||||
|
return f.Bytes(), http.StatusOK, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func RespondJSON(w http.ResponseWriter, message interface{}, code int, err error) (int, error) {
|
||||||
|
if message == nil {
|
||||||
|
message = map[string]string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, msgErr := json.Marshal(message)
|
||||||
|
|
||||||
|
if msgErr != nil {
|
||||||
|
return 500, msgErr
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(code)
|
||||||
|
w.Write(msg)
|
||||||
|
return 0, err
|
||||||
|
}
|
Loading…
Reference in New Issue