diff --git a/README.md b/README.md
index f687bef0..d41cdf45 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,7 @@
# Hugo add-on for Caddy
This is an add-on for Caddy which wants to deliver a good UI to edit the content of the website.
+
+```
+go-bindata -pkg assets -o assets/assets.go static/ templates/
+```
diff --git a/assets/assets.go b/assets/assets.go
new file mode 100644
index 00000000..2baf3bea
--- /dev/null
+++ b/assets/assets.go
@@ -0,0 +1,338 @@
+// Code generated by go-bindata.
+// sources:
+// static/css/main.css
+// static/css/normalize.css
+// templates/edit.tmpl
+// templates/footer.tmpl
+// templates/header.tmpl
+// DO NOT EDIT!
+
+package assets
+
+import (
+ "bytes"
+ "compress/gzip"
+ "fmt"
+ "io"
+ "strings"
+ "os"
+ "time"
+ "io/ioutil"
+ "path/filepath"
+)
+
+func bindataRead(data []byte, name string) ([]byte, error) {
+ gz, err := gzip.NewReader(bytes.NewBuffer(data))
+ if err != nil {
+ return nil, fmt.Errorf("Read %q: %v", name, 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 {
+ bytes []byte
+ info os.FileInfo
+}
+
+type bindataFileInfo struct {
+ 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 _staticCssMainCss = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
+
+func staticCssMainCssBytes() ([]byte, error) {
+ return bindataRead(
+ _staticCssMainCss,
+ "static/css/main.css",
+ )
+}
+
+func staticCssMainCss() (*asset, error) {
+ bytes, err := staticCssMainCssBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindataFileInfo{name: "static/css/main.css", size: 0, mode: os.FileMode(436), modTime: time.Unix(1442136876, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _staticCssNormalizeCss = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb4\x59\x61\x8f\xdb\x36\x12\xfd\xee\x5f\xc1\xa6\x28\x92\xec\xd9\x5e\xef\xa6\x69\x7b\xde\xeb\x87\x20\x4d\xae\x41\xd3\xe6\xd0\xe4\x70\x07\x04\x0b\x88\x92\x68\x9b\xb7\x92\x28\x88\x94\x77\x9d\xbb\xfb\xef\xf7\x66\x48\xca\x92\x2d\x6f\x52\xe0\x36\x01\x76\xbd\x12\x39\x1c\x0e\xe7\xbd\x79\x43\x9f\x9f\x7d\x25\x2a\xd3\x94\xb2\xd0\x9f\xd4\x3c\xb3\x56\x6c\x9f\xcd\x17\xf3\x4b\xf1\x1f\xf1\xeb\x9b\x0f\xe2\xad\xce\x54\x65\x15\xfe\x5a\x6b\x37\xd7\xe6\xbc\x1b\x2b\xce\xce\x27\x93\xf3\xb3\xb3\x89\x38\x13\x17\x73\xf1\x5e\x39\x91\xab\x95\x6c\x0b\x27\x56\xa6\xc2\x0f\x59\xea\x62\x27\x9c\x11\x56\x56\x76\x66\x55\xa3\x57\x73\x1a\x7c\x39\x17\x7f\x6b\xd4\x56\x61\x8c\x7e\xf7\x5e\x38\x75\xe7\x84\x25\x83\x32\xff\x57\x6b\x9d\x90\x2b\xa7\x1a\x61\x1a\x8d\x11\xd2\x69\x53\x89\x6c\x23\xab\xb5\x9a\x8a\x5b\xed\x36\xa6\xc5\x3a\xda\xca\xb4\xd0\xd5\x9a\xcc\xe1\x5f\x0b\xe3\xe2\x93\x31\x25\xd9\x87\x57\x1b\x57\x16\xe2\xdf\x13\xc1\x8e\xcc\xbc\x23\xcb\x9e\x1b\x57\xe2\x1c\x3e\xd3\x50\x21\x66\xa5\x9d\x91\x0b\x33\x72\x61\xe6\x5d\x58\x8a\x8b\xc5\xe2\x1b\x1e\x75\x19\x46\xdd\xaa\xf4\x46\xbb\xcf\x8e\xfc\x6f\x17\x92\xdf\x55\x69\xb6\xaa\x0b\x49\x29\x9b\xb5\xae\x82\x7f\xa9\xc9\x77\xec\x9f\x7f\xba\x14\x8b\x2b\x3f\x53\xfc\xfc\xe1\xd7\xb7\xcf\x69\x7f\x75\x21\x77\x34\x59\x57\x9a\x42\x60\x31\x58\xfc\xf8\x7f\xfb\xd7\x3f\xbb\x97\xa6\x69\x54\xe6\x44\x92\x16\x26\xbb\x49\xba\xc5\x2b\xe3\xbc\x03\x2a\x47\x1c\x1b\x21\xab\x5d\x70\x4f\x15\xaa\xe4\xd3\xab\xc4\x9b\x57\xe2\x87\xf3\x3f\xcf\xff\x88\x9d\x24\x57\x4e\xea\xc2\x26\x82\xfe\xb0\x6d\x89\x20\xec\x92\x60\xec\x62\x71\x7e\x71\x41\xd6\x64\x95\x8b\xd7\xba\x51\x2b\x73\xf7\xc7\xac\x97\x52\x57\x9d\xb5\x8b\x10\x70\xd9\x38\x9d\x15\x6a\x3a\x91\x56\xe7\xf8\x15\x5c\x98\x4e\x56\x7a\x9d\xc9\x9a\x22\xcc\x9f\xdb\x06\x2f\x57\xc6\x20\x01\xa7\x93\x8d\x92\x39\xff\x5e\x37\xa6\xad\xa7\x13\xb2\x8c\x9f\xaa\x6a\xa7\x93\x4a\x6e\xa7\x13\x0b\x87\x78\x66\xd8\x04\x1f\x69\x70\x6c\x29\xd8\xd1\xab\x5e\x46\x00\x24\xdd\x2e\x74\x85\xf4\x55\xb3\x7b\x36\x33\x0c\x2e\x30\xf3\x5b\x07\xbc\xad\xa2\xed\xc8\x42\xe0\xcf\x75\xc5\x47\x61\x56\x22\xa9\x1b\xb3\x6e\x94\xb5\xbc\xfb\x97\x9b\xc6\x94\x80\x4c\x88\xe1\x94\x03\xfa\xae\x56\x8d\x8c\x21\x69\x73\x6d\xa6\x93\x4c\x56\x5b\x89\x40\xc4\xc9\xd3\xc9\x16\x11\x32\xc3\xad\xf4\xbd\xed\x63\x27\x3a\x32\x63\x47\xb0\x65\x69\x15\x8d\x1c\xc3\x43\x84\x7c\x69\x10\xd4\x4a\xa4\x8d\xb9\x05\x16\xad\x58\xc1\xcf\xb8\x12\x10\x2d\x12\x76\x2c\xe9\xb0\x9e\x01\xc2\x8d\x29\xec\xbc\x07\x2a\x75\x97\xc1\x55\xb1\x51\x7a\xbd\xe1\x34\x24\x1e\x01\x6c\xd4\x16\x6c\x65\xfb\x1b\x5c\x22\xa4\x4f\x3e\x46\x1b\xd7\x4f\x87\xfb\xaa\x0c\x7c\xc5\x03\x6f\x68\x0f\x43\x76\xf8\x45\x9e\x53\x40\x44\xf2\x71\xa3\xf3\x5c\x55\xd7\x89\xb0\x6e\x47\xac\xc3\xe7\x54\xe3\xe5\x00\x04\xe7\x17\x0b\xf6\xf1\x67\xc4\x4f\xb8\x8d\x12\x89\x53\x25\xd6\x71\x2a\x39\x46\x0c\xb2\x7c\x2a\xde\xcb\x95\x6c\xf4\xb4\x9f\xeb\xe2\x2f\xe2\xf2\x32\x6c\x20\xae\x3b\x9d\x44\x43\x63\xde\x7b\xde\x78\xab\xab\x9b\x07\xe4\x88\x10\x77\xda\xd5\xba\x41\xa2\xa6\x32\xbb\x21\x54\xc0\xf1\xcc\x14\x80\x1d\x9f\xa2\x04\x1c\x30\xaa\x20\x5f\x3a\x3c\xc7\xd3\x60\xdf\xf7\xf3\x66\x3c\x6f\x29\x5c\x03\x56\xae\x65\x83\xe8\xf4\x83\xff\xa6\x44\x42\xc2\x56\x03\x0c\xca\x54\x17\xda\xed\xc4\xed\x46\x55\xc0\x78\x06\xb6\xcf\x39\x66\xb2\xb0\x06\xf9\x84\xbf\xc5\x06\x83\x1b\x8f\x1a\x59\x14\x5d\x76\xc5\xc5\x97\xde\x35\xe0\x7f\xc9\x23\xd9\x19\x64\x17\x25\x6b\x8f\x7d\x3f\x10\xbb\x17\xc8\xd3\x42\x58\x55\xca\x0a\xc9\xfd\x80\x41\x8d\x09\xf6\xb9\xac\x3a\xca\x15\x8f\xed\xb8\xb7\x34\x6d\x3e\x3a\xed\x0a\x75\xed\x43\x6c\x1a\x00\x6c\x96\x1a\xe7\x4c\x89\xf2\x54\xdf\x89\x1c\x9f\x55\x3e\x96\xdb\xb4\xb4\xc2\x5e\x1d\x95\xe9\x24\x35\x05\xa6\x32\x7d\xc4\x74\xfc\xf6\x4f\xf7\x2c\x9d\x82\xf9\x80\x2b\xb8\xde\xd5\xda\xdb\x80\x24\x32\x75\x6a\xc1\x91\xbd\xfa\x25\x8e\x57\xc8\x57\xd5\xde\x36\x3b\x0b\x32\x72\x60\x9b\x6c\xcc\xf8\x16\x36\xa0\x0b\x80\xbc\xcd\x45\x12\xe6\xb0\xae\x80\x59\x5f\x69\x99\x55\xf0\x2b\x09\xd4\x9d\xf0\xbb\x24\x94\x87\x84\x8c\x11\x57\x20\x0d\xec\x17\x47\x61\x73\xd1\x73\x11\xcb\x2d\xc5\xa5\x2a\xaf\xfa\xc5\x7d\xfe\xdd\xf7\xaa\x1c\x27\x97\x7b\xcf\x3e\x2c\x00\x3b\x37\x07\xe8\x59\x8a\xaf\x57\xab\x05\x2d\x12\x60\xf4\xf5\x62\x31\x6a\x5f\x57\xd8\x8f\xd5\xd6\x91\x61\x72\xbd\x8b\x11\x6b\x34\x0e\xcf\x38\x66\x6c\x49\x0f\x0f\x76\xf6\x03\xb4\xce\x08\xa7\xa3\x8a\xa7\x21\x94\xb6\xad\xf1\x69\xb5\xa2\xf8\x12\x9b\x73\xe1\xf0\xfc\x9a\x9c\x5a\xa9\xa5\x44\x6a\xeb\xc3\xc5\xbe\x7f\xfe\x0d\xed\xb0\x67\x81\xa1\x2a\x44\x6d\x2c\x8b\xa2\x25\xe8\x01\xb4\x08\x60\x5f\xdd\x57\x8c\xc8\xe1\x68\xde\x99\x7a\x29\x66\x8b\xf9\x73\x3a\x22\x7e\x9e\x06\xd4\x78\xb8\xe0\xd5\x65\x7c\x07\x42\x78\x55\xa6\x0a\x1c\x9c\xfb\xac\xa8\xdc\x83\x33\xac\x47\xaf\xa7\x3a\x5d\x91\x58\x41\x76\x8e\xd6\x8f\x48\xac\xba\x5c\xf7\x70\x7f\x50\xc3\xa2\xde\x20\xce\x5b\x15\xe6\x96\xf3\xcc\x97\x95\x60\x2b\x10\x4c\x3c\x8a\xed\x9a\x2b\xe6\xb2\x81\x06\xf2\xc5\x32\x4e\x5d\x86\x79\x31\x34\x7f\x25\x51\x44\x47\xfc\xe0\xa1\x89\xb9\x1c\x20\x3c\x0a\x15\x4e\x3e\x0f\xd1\xb0\x15\xaf\xe6\x06\x2a\xfb\x02\x28\xfc\x76\x51\xdf\x8d\x01\x25\xd7\xc8\x59\x54\x21\xe8\x07\x91\x2a\x77\xab\xd4\x1e\xfe\x64\xdb\xa0\xf6\x35\x87\x99\xbb\xf1\x85\x64\x56\x9a\x4f\x20\xdc\x3b\xca\x5b\x44\x64\x19\x43\x42\xcf\xae\xf8\x68\x4e\xbe\x1a\x55\x1e\x2f\x31\x06\x5a\x73\x7f\x6a\xe3\xb8\xa9\xc3\xf6\xf6\x27\x24\x5b\x67\xc6\x36\x67\x72\x20\x53\x95\xc9\xac\x45\x37\xd1\x43\x3e\xf6\x8b\x9c\xa1\x43\x1c\x5f\x21\x33\x24\x96\x6f\xd2\x9c\xf4\x21\x3e\x59\x59\xd6\xc7\x7d\x55\x69\x2a\x83\x12\x9e\x41\x6d\x76\x1f\xaf\x86\x50\xbe\xd8\x43\xea\x35\x64\xec\x03\x16\xd5\x5f\x2a\x73\x5b\x81\x33\x4a\xed\x7b\x47\xf0\xc0\x2e\x36\x61\xd3\x40\xdc\xbd\x64\x11\xe8\x2e\xa1\x1d\xff\x49\xbb\x47\xa0\x11\xc9\x9d\x9f\xac\x72\xb2\x16\xe9\x99\xe4\x35\xd8\x04\x50\x4a\xa6\xa2\xad\x0a\x0a\xaa\xa4\x82\xd9\x70\xc1\x84\x56\x81\xb2\x86\x44\xd1\x96\x8a\x69\x88\xde\xb1\xec\xf7\x5a\x89\x12\x38\x55\x3e\xea\x48\x2a\x5a\x6b\x1e\x1a\x59\xef\xbd\xb6\xb6\x45\xd0\x3c\x8b\xda\x30\x0b\x2e\xf8\xb6\x17\x6c\x14\xe8\xc0\xc6\xd6\x20\xda\xe7\x93\x0d\xce\x68\x24\xf2\xa9\x95\x9e\xcd\x0f\x40\xc5\x6e\x77\x18\x70\x68\xdb\xbf\x58\x03\xb4\x20\x4e\xb4\x40\xba\xaa\x5b\x37\x9d\x98\xda\x85\x6e\xc9\x87\x8b\xb4\xeb\x9d\x83\xbc\xf3\xfa\x2f\x54\xab\xe0\x4d\xbf\x95\x20\xd7\x87\x2f\x42\xe7\xbd\x6f\x91\xe9\xe1\xb3\x61\x53\xd1\x69\xf4\x88\x81\xa4\x13\x33\x9e\xad\x92\x43\x25\x35\x70\xfb\x00\x3e\x5b\x6d\x35\xe2\xfb\xd9\x3a\x9a\xf0\x2d\x00\x2b\x57\xb4\x9c\x65\x12\xdd\x96\x60\x0f\xdf\x84\x7a\xf3\xb1\x24\xfa\xc4\xe1\xc8\xbf\x00\xc8\x3c\x95\xd0\xcc\xd8\xdc\x74\x07\x0a\xa9\xc6\x87\x16\x0c\x1e\xaf\xb4\x95\x45\xeb\x3b\x9c\x5e\x47\x1c\x16\xf3\x62\xae\xef\xcb\xfe\x10\xa7\x07\x72\x72\xd0\x0d\xee\x4d\x05\x57\xef\x35\x75\x70\xf0\x7e\x8a\x2f\xae\x03\x67\x07\x0d\x4a\x44\xc2\x8b\xad\xd1\x39\xf7\x11\xff\x50\xe9\x2f\xd8\x61\xda\x32\xf9\xbc\xa8\xf2\x86\xde\x7c\x3b\x5f\xcc\xcf\xa8\xfc\x81\xdb\x9e\x5c\x3e\x05\x72\x49\x61\xee\x90\xca\x5c\xe7\x63\x77\x18\xe0\xc2\xe1\xe5\x7e\x35\x19\xf6\x89\x3d\x4c\xe8\x2a\xf6\x0f\x74\x13\xc5\xfb\xca\xa0\x1f\x6f\xbc\x50\xe4\xb4\x4d\x84\xdb\xd5\xca\x86\x46\x32\x22\x24\xb6\x20\xad\x8d\x06\x24\xb7\x3b\x21\x0d\xb2\x1d\x41\x32\x6b\x1b\x8b\x03\xf7\x76\x63\xdd\xd0\xa5\x5c\xab\x19\xd9\x0c\x7e\xc6\x65\xba\x42\x62\x0f\x82\xc8\x17\x56\x3c\xe8\x23\x4d\xfb\xf1\x91\x7f\xf1\xe8\x7a\xda\x41\xa4\xff\x96\xaa\x9f\xc3\xcb\xc1\x43\x48\x19\xf0\xd6\x23\xdf\x05\xc4\xfb\x2a\x59\xd7\x4a\x36\x74\x82\x20\x42\xb6\xd9\xc7\x96\xf7\x7e\x09\x41\xa5\x51\x95\x9a\x31\x84\xfd\xae\x66\xb6\x77\xb3\x17\xf6\x4b\x49\x3e\xca\x46\xdd\x9e\x3e\xc6\xd7\xd7\x83\xdd\x75\x4f\x3d\x1d\x84\xf5\x83\xf5\xab\xe3\xeb\x33\x5d\x55\xc0\x4a\x2d\xf3\x9c\x58\x8c\xe2\x17\x14\xd2\x80\x9f\x06\x2b\x2f\x97\x5c\x8f\xb9\x51\x9c\xf1\xfc\x10\xa7\xe3\x17\x87\xc2\x49\xc4\x95\x4e\x5c\x05\xec\x57\x24\x9a\x19\x11\xb8\xa0\x94\x78\xd6\xad\xe5\xd7\x5f\xe9\xb2\x36\x0d\x30\xc4\xf2\x97\x8c\x51\xf2\xff\xfd\x85\x4f\x19\xbb\x51\x5d\xb9\xe0\x79\xec\xd1\x40\xf1\xfa\xfb\xd6\x41\x6f\xec\x1e\x5b\x94\xee\xcc\x94\x25\xd5\x6f\x82\x93\x74\x62\x67\x5a\xb0\x47\xf5\x18\x32\xdf\xd1\x7d\x81\xdb\xe7\x3b\x56\x44\x8b\x3c\x28\x1a\x61\x27\x30\x04\xff\xfc\x0b\x7f\xd5\x9a\x1b\x65\xc9\x08\xf6\x5b\x13\x7c\xf6\xda\x65\x1a\x83\x33\xa5\x8b\xbb\x5b\x9d\xbb\x0d\x99\x8a\xc0\x0e\x21\xc2\x78\xe1\xc7\x77\x4c\xdc\x93\x3c\xc9\xf1\x75\x09\xa0\x3a\xbc\xd5\x89\x87\x3d\xa6\x75\x7b\xe9\x9e\x6d\x54\x76\x03\x93\x87\x30\x68\x24\x08\xe2\x51\xec\x85\xf7\xc2\xab\xeb\x8b\xef\xfa\x65\xa7\x77\xde\x23\x77\x56\xaf\xf5\x1d\x1f\xd7\x00\xe5\x94\xfb\xbe\x04\x3e\xe6\xba\xd0\x70\xf4\xce\x73\x15\x3e\x05\x9c\xd9\x39\x49\x1d\x91\xa1\x14\x4b\x7f\xf0\x49\x27\x88\x22\x8f\x13\x83\xf0\x4d\x91\xcf\x99\x29\x7a\x5b\x91\xc9\xd6\xe2\xcd\xd1\xb2\x7e\x28\xd9\x39\x5c\x89\x82\xec\x6f\xc8\xfd\x35\x4c\x12\xe0\x94\x70\xf4\x89\x94\x93\x91\xf8\x55\x2d\x7a\x9b\xe6\xd1\x35\x50\x11\xb8\x82\x21\x31\xb3\x10\xf5\xb3\x41\x55\x3f\x39\xc1\xb4\x6e\x38\x81\x83\x1e\x13\xf7\x50\x8c\xf6\x92\x24\xd9\xd3\xd2\xbe\x60\x5b\x3c\xc9\x36\x2b\xad\x8a\x3c\x39\x79\x27\x40\xe9\xd2\x59\xd9\x1f\x6f\xd2\xbb\xc3\x88\xc7\x3c\x6e\x24\x30\xf2\x13\x1c\x5c\xd1\x52\x77\x45\x9c\xc0\x91\x5a\xb5\x0e\x0d\xc3\x0c\xa4\x6f\x56\x4f\x47\x02\xe6\xfd\xbb\x87\x5f\x29\xd2\xec\xfe\xf0\xeb\x85\xfb\x7b\x83\x68\xe8\xd4\x90\x1e\x5b\x9f\xb4\xf2\x05\xac\xe9\x9d\x47\x72\xc1\xd3\x22\xe6\xcd\x58\x7c\xa2\x20\xe6\x60\x87\xb7\x4f\x30\x9e\x65\x89\x1f\xf2\x94\x0a\x68\x1d\x52\x74\x60\x90\xdb\x56\x7a\x1c\x96\xf3\x94\xb6\x91\x96\x8c\x45\x77\x9e\x70\xd5\xee\x82\x85\xaa\xd8\xc5\xf0\xbe\xb0\xef\xd3\xce\x3f\x99\xf9\xa5\x47\x53\xf5\xe4\x1c\x40\xc7\x34\x9e\xe8\x4e\x9d\xe2\xa1\x68\xf9\x89\xef\xe3\x45\x4f\xfe\xf9\x14\x9b\x06\x65\xea\xb5\x54\xd8\x5c\xd7\x7b\x62\x63\x94\x91\xfd\xfa\x42\x37\x71\xd6\x14\x10\x39\x5f\x67\x0b\xfa\x3f\xb8\x23\x12\x97\xf5\xdd\xb0\x00\xcd\x9f\x3d\xa7\x5b\xa3\xf9\x77\x97\xfe\xf7\xf7\xfb\x7b\x89\xa3\xaf\x13\x58\x57\x27\x63\x7a\x7f\x4c\xff\xf6\x38\x37\x1e\x8a\x35\xa2\x56\x06\x95\x40\xd0\x55\xec\x63\xa6\x21\xba\x5b\xa7\x1b\x78\xcd\xcc\xb3\x13\x9f\x54\x63\xf8\x41\xdc\x5e\xac\xf8\x85\x5a\xa3\x10\x1d\x14\xd3\x2f\x26\xd9\x83\x2f\xca\xba\x2f\x37\x6c\x06\x39\x57\xa4\xb2\x39\x21\xe1\x07\x8d\xc5\xe9\x1e\xf8\x27\xae\x89\x51\x50\x33\xdb\xf6\x6e\x2a\x13\xa4\x63\x5d\x17\x1a\x81\x42\x9f\x28\x45\xd3\x52\x08\x52\x98\xe3\x5c\x14\xbf\xbd\xfb\xf0\x6a\xc9\xb3\x3a\x05\x24\x2b\x0a\xb3\x95\x2b\x85\x36\x29\x55\x81\x7a\xf3\xfd\x97\x2e\x23\xed\x65\x70\x39\x76\x47\xf7\xde\x97\x8a\x0f\xa4\x90\x1e\xfe\x32\xbf\x34\x16\xdb\x40\xb3\x4e\xe7\x1f\xa5\xab\x63\x59\x0c\x5c\x15\xf1\x70\xfd\x93\xde\xcd\x32\x72\xad\x90\xb5\x55\x44\x42\xfe\xd3\xd5\xfe\x65\xb0\x17\xf5\x93\xcb\xd1\x00\x6e\x78\xf6\x50\x59\xfd\x2f\x00\x00\xff\xff\xb4\x45\x1a\x03\x76\x1e\x00\x00")
+
+func staticCssNormalizeCssBytes() ([]byte, error) {
+ return bindataRead(
+ _staticCssNormalizeCss,
+ "static/css/normalize.css",
+ )
+}
+
+func staticCssNormalizeCss() (*asset, error) {
+ bytes, err := staticCssNormalizeCssBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindataFileInfo{name: "static/css/normalize.css", size: 7798, mode: os.FileMode(436), modTime: time.Unix(1442136889, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _templatesEditTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xaa\xae\x56\xf6\x70\x75\x74\x71\x0d\x52\xae\xad\xe5\xe2\xb2\x29\x49\xad\x28\x49\x2c\x4a\x4d\xb4\xab\xae\x56\xd0\x73\xca\x4f\xa9\xd4\x0b\x4b\x2c\x32\x54\xa8\xad\xb5\xd1\x87\x4b\x71\x71\x01\x35\xb9\xf9\xfb\x87\x40\x34\x01\x02\x00\x00\xff\xff\x60\x7d\x92\x18\x42\x00\x00\x00")
+
+func templatesEditTmplBytes() ([]byte, error) {
+ return bindataRead(
+ _templatesEditTmpl,
+ "templates/edit.tmpl",
+ )
+}
+
+func templatesEditTmpl() (*asset, error) {
+ bytes, err := templatesEditTmplBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindataFileInfo{name: "templates/edit.tmpl", size: 66, mode: os.FileMode(436), modTime: time.Unix(1442142830, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _templatesFooterTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb2\x49\xcb\xcf\x2f\x49\x2d\xb2\xe3\xe2\xb2\xd1\x87\x31\x6d\xf4\x93\xf2\x53\x2a\x41\x74\x46\x49\x6e\x8e\x1d\x17\x20\x00\x00\xff\xff\x61\xeb\xb2\x38\x24\x00\x00\x00")
+
+func templatesFooterTmplBytes() ([]byte, error) {
+ return bindataRead(
+ _templatesFooterTmpl,
+ "templates/footer.tmpl",
+ )
+}
+
+func templatesFooterTmpl() (*asset, error) {
+ bytes, err := templatesFooterTmplBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindataFileInfo{name: "templates/footer.tmpl", size: 36, mode: os.FileMode(436), modTime: time.Unix(1442138891, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _templatesHeaderTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x90\x31\x4f\xc3\x30\x10\x85\xf7\xfe\x0a\x63\x56\xdc\x88\x8d\x21\x8e\x84\x4a\x07\x26\x18\x8a\x04\xa3\xeb\xbc\xd4\x07\x67\xbb\xc4\xd7\x56\xa5\xea\x7f\x27\xa1\x02\x15\x89\x89\xc9\xdf\xf9\xde\x7b\x3a\xbd\xfa\xe2\xee\x61\xb6\x78\x79\x9c\xab\x20\x91\x9b\x49\x3d\x3e\xca\xb3\x2b\xc5\xea\x94\xcd\x6b\xd1\x8a\x5d\x5a\x59\x8d\xa4\x9b\x89\x52\x75\x80\x6b\x47\x18\x30\x42\x9c\xf2\xc1\xf5\x05\x62\xf5\x46\x3a\x73\xa3\xcf\x57\x41\x64\x6d\xf0\xbe\xa1\xad\xd5\xcf\xe6\xe9\xd6\xcc\x72\x5c\x3b\xa1\x25\x43\x2b\x9f\x93\x20\x0d\xbe\xfb\xb9\x45\xbb\xc2\x2f\x67\x72\x11\x56\x6f\x09\xbb\x75\xee\xe5\x4c\xbc\xa3\x56\x82\x6d\xb1\x25\x0f\xf3\x35\x5c\x29\x4a\x24\xe4\xd8\x14\xef\x18\xf6\xfa\x8f\x20\x09\x88\x30\x3e\x73\xee\xcf\xb2\x2e\xbb\xae\xfb\x16\x0b\x09\xa3\x39\x1c\xd4\x74\x31\x92\x3a\x1e\xeb\xea\xf4\x77\xda\x33\xa5\x37\xd5\x83\xad\x2e\xb2\x67\x94\x00\x0c\x67\x85\x1e\x9d\xd5\x95\x6b\x23\xa5\x6a\xa8\x0c\x52\x2a\x5f\x4a\x95\x72\x1f\x1d\xd3\x07\xa6\xc3\xa4\xff\x15\x11\x1d\xa5\x1f\x77\x5d\x9d\x5a\x1f\x71\x99\xdb\x7d\x33\xf9\x0c\x00\x00\xff\xff\xf3\xee\xa9\xf9\xb8\x01\x00\x00")
+
+func templatesHeaderTmplBytes() ([]byte, error) {
+ return bindataRead(
+ _templatesHeaderTmpl,
+ "templates/header.tmpl",
+ )
+}
+
+func templatesHeaderTmpl() (*asset, error) {
+ bytes, err := templatesHeaderTmplBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindataFileInfo{name: "templates/header.tmpl", size: 440, mode: os.FileMode(436), modTime: time.Unix(1442141496, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+// Asset loads and returns the asset for the given name.
+// It returns an error if the asset could not be found or
+// could not be loaded.
+func Asset(name string) ([]byte, error) {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ if f, ok := _bindata[cannonicalName]; ok {
+ a, err := f()
+ if err != nil {
+ return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
+ }
+ return a.bytes, nil
+ }
+ return nil, fmt.Errorf("Asset %s not found", name)
+}
+
+// MustAsset is like Asset but panics when Asset would return an error.
+// It simplifies safe initialization of global variables.
+func MustAsset(name string) []byte {
+ a, err := Asset(name)
+ if (err != nil) {
+ panic("asset: Asset(" + name + "): " + err.Error())
+ }
+
+ return a
+}
+
+// AssetInfo loads and returns the asset info for the given name.
+// It returns an error if the asset could not be found or
+// could not be loaded.
+func AssetInfo(name string) (os.FileInfo, error) {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ if f, ok := _bindata[cannonicalName]; ok {
+ a, err := f()
+ if err != nil {
+ return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
+ }
+ return a.info, nil
+ }
+ return nil, fmt.Errorf("AssetInfo %s not found", name)
+}
+
+// AssetNames returns the names of the assets.
+func AssetNames() []string {
+ names := make([]string, 0, len(_bindata))
+ for name := range _bindata {
+ names = append(names, name)
+ }
+ return names
+}
+
+// _bindata is a table, holding each asset generator, mapped to its name.
+var _bindata = map[string]func() (*asset, error){
+ "static/css/main.css": staticCssMainCss,
+ "static/css/normalize.css": staticCssNormalizeCss,
+ "templates/edit.tmpl": templatesEditTmpl,
+ "templates/footer.tmpl": templatesFooterTmpl,
+ "templates/header.tmpl": templatesHeaderTmpl,
+}
+
+// AssetDir returns the file names below a certain
+// directory embedded in the file by go-bindata.
+// For example if you run go-bindata on data/... and data contains the
+// following hierarchy:
+// data/
+// foo.txt
+// img/
+// a.png
+// b.png
+// then AssetDir("data") would return []string{"foo.txt", "img"}
+// AssetDir("data/img") would return []string{"a.png", "b.png"}
+// AssetDir("foo.txt") and AssetDir("notexist") would return an error
+// AssetDir("") will return []string{"data"}.
+func AssetDir(name string) ([]string, error) {
+ node := _bintree
+ if len(name) != 0 {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ pathList := strings.Split(cannonicalName, "/")
+ for _, p := range pathList {
+ node = node.Children[p]
+ if node == nil {
+ return nil, fmt.Errorf("Asset %s not found", name)
+ }
+ }
+ }
+ if node.Func != nil {
+ return nil, fmt.Errorf("Asset %s not found", name)
+ }
+ rv := make([]string, 0, len(node.Children))
+ for childName := range node.Children {
+ rv = append(rv, childName)
+ }
+ return rv, nil
+}
+
+type bintree struct {
+ Func func() (*asset, error)
+ Children map[string]*bintree
+}
+var _bintree = &bintree{nil, map[string]*bintree{
+ "static": &bintree{nil, map[string]*bintree{
+ "css": &bintree{nil, map[string]*bintree{
+ "main.css": &bintree{staticCssMainCss, map[string]*bintree{
+ }},
+ "normalize.css": &bintree{staticCssNormalizeCss, map[string]*bintree{
+ }},
+ }},
+ }},
+ "templates": &bintree{nil, map[string]*bintree{
+ "edit.tmpl": &bintree{templatesEditTmpl, map[string]*bintree{
+ }},
+ "footer.tmpl": &bintree{templatesFooterTmpl, map[string]*bintree{
+ }},
+ "header.tmpl": &bintree{templatesHeaderTmpl, map[string]*bintree{
+ }},
+ }},
+}}
+
+// RestoreAsset restores an asset under the given directory
+func RestoreAsset(dir, name string) error {
+ data, err := Asset(name)
+ if err != nil {
+ return err
+ }
+ info, err := AssetInfo(name)
+ if err != nil {
+ return err
+ }
+ err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
+ if err != nil {
+ return err
+ }
+ err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// RestoreAssets restores an asset under the given directory recursively
+func RestoreAssets(dir, name string) error {
+ children, err := AssetDir(name)
+ // File
+ if err != nil {
+ return RestoreAsset(dir, name)
+ }
+ // Dir
+ for _, child := range children {
+ err = RestoreAssets(dir, filepath.Join(name, child))
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func _filePath(dir, name string) string {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
+}
+
diff --git a/edit/edit.go b/edit/edit.go
index e2fa2497..a898f483 100644
--- a/edit/edit.go
+++ b/edit/edit.go
@@ -4,9 +4,12 @@ import (
"io/ioutil"
"net/http"
"os"
+
+ "github.com/hacdias/caddy-hugo/page"
)
-type Page struct {
+type editPage struct {
+ Var1 string
}
// Execute sth
@@ -14,15 +17,23 @@ func Execute(w http.ResponseWriter, r *http.Request, file string) (int, error) {
if r.Method == "POST" {
// it's saving the post
} else {
- // check if the file exists
if _, err := os.Stat(file); os.IsNotExist(err) {
return 404, nil
}
- file, _ := ioutil.ReadFile(file)
+ file, err := ioutil.ReadFile(file)
- // render the template here
- w.Write([]byte(string(file)))
+ if err != nil {
+ return 500, err
+ }
+
+ editInfo := new(editPage)
+ editInfo.Var1 = string(file)
+
+ page := new(page.Info)
+ page.Title = "Edit"
+ page.Body = editInfo
+ return page.Render("edit", w)
}
return 200, nil
diff --git a/hugo.go b/hugo.go
index 7b52ba34..7d4554ca 100644
--- a/hugo.go
+++ b/hugo.go
@@ -1,14 +1,27 @@
+//go:generate go-bindata -pkg assets -o assets/assets.go static/css/ templates/
+
package hugo
import (
"net/http"
+ "strings"
- "github.com/hacdias/caddy-hugo/routing"
+ "github.com/hacdias/caddy-hugo/assets"
+ "github.com/hacdias/caddy-hugo/edit"
"github.com/mholt/caddy/config/setup"
"github.com/mholt/caddy/middleware"
"github.com/spf13/hugo/commands"
)
+const (
+ mainURL string = "/admin"
+ contentURL string = mainURL + "/content"
+ browseURL string = mainURL + "/browse"
+ editURL string = mainURL + "/edit"
+ settingsURL string = mainURL + "/settings"
+ assetsURL string = mainURL + "/assets"
+)
+
// Setup function
func Setup(c *setup.Controller) (middleware.Middleware, error) {
commands.Execute()
@@ -21,9 +34,47 @@ func Setup(c *setup.Controller) (middleware.Middleware, error) {
type handler struct{ Next middleware.Handler }
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {
- if middleware.Path(r.URL.Path).Matches("/admin") {
- return routing.Route(w, r)
+ if urlMatch(r, "/admin") {
+ return route(w, r)
}
return h.Next.ServeHTTP(w, r)
}
+
+func route(w http.ResponseWriter, r *http.Request) (int, error) {
+ if urlMatch(r, contentURL) {
+ // content folder management
+ w.Write([]byte("Show Content Folder"))
+ } else if urlMatch(r, browseURL) {
+ // browse files
+ w.Write([]byte("Show Data Folder"))
+ } else if urlMatch(r, editURL) {
+ // edit file
+ return edit.Execute(w, r, strings.Replace(r.URL.Path, editURL+"/", "", 1))
+ } else if urlMatch(r, settingsURL) {
+ // edit settings
+ w.Write([]byte("Settings Page"))
+
+ } else if urlMatch(r, assetsURL) {
+ // assets like css, javascript and images
+ fileName := strings.Replace(r.URL.Path, assetsURL, "static", 1)
+ file, err := assets.Asset(fileName)
+
+ if err != nil {
+ return 404, nil
+ }
+
+ w.Write(file)
+ } else if r.URL.Path == mainURL || r.URL.Path == mainURL+"/" {
+ // dashboard
+ w.Write([]byte("Dashboard"))
+ } else {
+ return 404, nil
+ }
+
+ return 200, nil
+}
+
+func urlMatch(r *http.Request, str string) bool {
+ return middleware.Path(r.URL.Path).Matches(str)
+}
diff --git a/page/page.go b/page/page.go
new file mode 100644
index 00000000..fbbf847d
--- /dev/null
+++ b/page/page.go
@@ -0,0 +1,59 @@
+package page
+
+import (
+ "html/template"
+ "net/http"
+ "strings"
+
+ "github.com/hacdias/caddy-hugo/assets"
+)
+
+const (
+ templateExtension = ".tmpl"
+ headerMark = "{{#HEADER#}}"
+ footerMark = "{{#FOOTER#}}"
+)
+
+// Info type
+type Info struct {
+ Title string
+ Body interface{}
+}
+
+// Render the page
+func (p *Info) Render(name string, w http.ResponseWriter) (int, error) {
+ rawHeader, err := assets.Asset("templates/header" + templateExtension)
+
+ if err != nil {
+ return 500, err
+ }
+
+ header := string(rawHeader)
+
+ rawFooter, err := assets.Asset("templates/footer" + templateExtension)
+
+ if err != nil {
+ return 500, err
+ }
+
+ footer := string(rawFooter)
+
+ rawPage, err := assets.Asset("templates/" + name + templateExtension)
+
+ if err != nil {
+ return 500, err
+ }
+
+ page := string(rawPage)
+ page = strings.Replace(page, headerMark, header, -1)
+ page = strings.Replace(page, footerMark, footer, -1)
+
+ tpl, err := template.New("page").Parse(page)
+
+ if err != nil {
+ return 500, err
+ }
+
+ tpl.Execute(w, p)
+ return 200, nil
+}
diff --git a/routing/routing.go b/routing/routing.go
deleted file mode 100644
index 8b655067..00000000
--- a/routing/routing.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package routing
-
-import (
- "net/http"
- "strings"
-
- "github.com/hacdias/caddy-hugo/edit"
- "github.com/mholt/caddy/middleware"
-)
-
-const (
- mainURL string = "/admin"
- contentURL string = mainURL + "/content"
- dataURL string = mainURL + "/data"
- editURL string = mainURL + "/edit"
- newURL string = mainURL + "/new"
- settingsURL string = mainURL + "/settings"
- staticURL string = mainURL + "/static"
-)
-
-// Route the admin path
-func Route(w http.ResponseWriter, r *http.Request) (int, error) {
- if middleware.Path(r.URL.Path).Matches(contentURL) {
- w.Write([]byte("Show Content Folder"))
- } else if middleware.Path(r.URL.Path).Matches(dataURL) {
- w.Write([]byte("Show Data Folder"))
- } else if middleware.Path(r.URL.Path).Matches(editURL) {
- return edit.Execute(w, r, strings.Replace(r.URL.Path, editURL+"/", "", 1))
- } else if middleware.Path(r.URL.Path).Matches(newURL) {
- w.Write([]byte("New Thing Page"))
- } else if middleware.Path(r.URL.Path).Matches(settingsURL) {
- w.Write([]byte("Settings Page"))
- } else if middleware.Path(r.URL.Path).Matches(staticURL) {
- w.Write([]byte("Static things management"))
- } else if r.URL.Path == mainURL || r.URL.Path == mainURL+"/" {
- w.Write([]byte("Dashboard"))
- } else {
- return 404, nil
- }
-
- return 200, nil
-}
diff --git a/static/css/main.css b/static/css/main.css
new file mode 100644
index 00000000..e69de29b
diff --git a/static/css/normalize.css b/static/css/normalize.css
new file mode 100644
index 00000000..458eea1e
--- /dev/null
+++ b/static/css/normalize.css
@@ -0,0 +1,427 @@
+/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
+
+/**
+ * 1. Set default font family to sans-serif.
+ * 2. Prevent iOS text size adjust after orientation change, without disabling
+ * user zoom.
+ */
+
+html {
+ font-family: sans-serif; /* 1 */
+ -ms-text-size-adjust: 100%; /* 2 */
+ -webkit-text-size-adjust: 100%; /* 2 */
+}
+
+/**
+ * Remove default margin.
+ */
+
+body {
+ margin: 0;
+}
+
+/* HTML5 display definitions
+ ========================================================================== */
+
+/**
+ * Correct `block` display not defined for any HTML5 element in IE 8/9.
+ * Correct `block` display not defined for `details` or `summary` in IE 10/11
+ * and Firefox.
+ * Correct `block` display not defined for `main` in IE 11.
+ */
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section,
+summary {
+ display: block;
+}
+
+/**
+ * 1. Correct `inline-block` display not defined in IE 8/9.
+ * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
+ */
+
+audio,
+canvas,
+progress,
+video {
+ display: inline-block; /* 1 */
+ vertical-align: baseline; /* 2 */
+}
+
+/**
+ * Prevent modern browsers from displaying `audio` without controls.
+ * Remove excess height in iOS 5 devices.
+ */
+
+audio:not([controls]) {
+ display: none;
+ height: 0;
+}
+
+/**
+ * Address `[hidden]` styling not present in IE 8/9/10.
+ * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
+ */
+
+[hidden],
+template {
+ display: none;
+}
+
+/* Links
+ ========================================================================== */
+
+/**
+ * Remove the gray background color from active links in IE 10.
+ */
+
+a {
+ background-color: transparent;
+}
+
+/**
+ * Improve readability when focused and also mouse hovered in all browsers.
+ */
+
+a:active,
+a:hover {
+ outline: 0;
+}
+
+/* Text-level semantics
+ ========================================================================== */
+
+/**
+ * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
+ */
+
+abbr[title] {
+ border-bottom: 1px dotted;
+}
+
+/**
+ * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
+ */
+
+b,
+strong {
+ font-weight: bold;
+}
+
+/**
+ * Address styling not present in Safari and Chrome.
+ */
+
+dfn {
+ font-style: italic;
+}
+
+/**
+ * Address variable `h1` font-size and margin within `section` and `article`
+ * contexts in Firefox 4+, Safari, and Chrome.
+ */
+
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
+}
+
+/**
+ * Address styling not present in IE 8/9.
+ */
+
+mark {
+ background: #ff0;
+ color: #000;
+}
+
+/**
+ * Address inconsistent and variable font size in all browsers.
+ */
+
+small {
+ font-size: 80%;
+}
+
+/**
+ * Prevent `sub` and `sup` affecting `line-height` in all browsers.
+ */
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+/* Embedded content
+ ========================================================================== */
+
+/**
+ * Remove border when inside `a` element in IE 8/9/10.
+ */
+
+img {
+ border: 0;
+}
+
+/**
+ * Correct overflow not hidden in IE 9/10/11.
+ */
+
+svg:not(:root) {
+ overflow: hidden;
+}
+
+/* Grouping content
+ ========================================================================== */
+
+/**
+ * Address margin not present in IE 8/9 and Safari.
+ */
+
+figure {
+ margin: 1em 40px;
+}
+
+/**
+ * Address differences between Firefox and other browsers.
+ */
+
+hr {
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ height: 0;
+}
+
+/**
+ * Contain overflow in all browsers.
+ */
+
+pre {
+ overflow: auto;
+}
+
+/**
+ * Address odd `em`-unit font size rendering in all browsers.
+ */
+
+code,
+kbd,
+pre,
+samp {
+ font-family: monospace, monospace;
+ font-size: 1em;
+}
+
+/* Forms
+ ========================================================================== */
+
+/**
+ * Known limitation: by default, Chrome and Safari on OS X allow very limited
+ * styling of `select`, unless a `border` property is set.
+ */
+
+/**
+ * 1. Correct color not being inherited.
+ * Known issue: affects color of disabled elements.
+ * 2. Correct font properties not being inherited.
+ * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
+ */
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ color: inherit; /* 1 */
+ font: inherit; /* 2 */
+ margin: 0; /* 3 */
+}
+
+/**
+ * Address `overflow` set to `hidden` in IE 8/9/10/11.
+ */
+
+button {
+ overflow: visible;
+}
+
+/**
+ * Address inconsistent `text-transform` inheritance for `button` and `select`.
+ * All other form control elements do not inherit `text-transform` values.
+ * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
+ * Correct `select` style inheritance in Firefox.
+ */
+
+button,
+select {
+ text-transform: none;
+}
+
+/**
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
+ * and `video` controls.
+ * 2. Correct inability to style clickable `input` types in iOS.
+ * 3. Improve usability and consistency of cursor style between image-type
+ * `input` and others.
+ */
+
+button,
+html input[type="button"], /* 1 */
+input[type="reset"],
+input[type="submit"] {
+ -webkit-appearance: button; /* 2 */
+ cursor: pointer; /* 3 */
+}
+
+/**
+ * Re-set default cursor for disabled elements.
+ */
+
+button[disabled],
+html input[disabled] {
+ cursor: default;
+}
+
+/**
+ * Remove inner padding and border in Firefox 4+.
+ */
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+/**
+ * Address Firefox 4+ setting `line-height` on `input` using `!important` in
+ * the UA stylesheet.
+ */
+
+input {
+ line-height: normal;
+}
+
+/**
+ * It's recommended that you don't attempt to style these elements.
+ * Firefox's implementation doesn't respect box-sizing, padding, or width.
+ *
+ * 1. Address box sizing set to `content-box` in IE 8/9/10.
+ * 2. Remove excess padding in IE 8/9/10.
+ */
+
+input[type="checkbox"],
+input[type="radio"] {
+ box-sizing: border-box; /* 1 */
+ padding: 0; /* 2 */
+}
+
+/**
+ * Fix the cursor style for Chrome's increment/decrement buttons. For certain
+ * `font-size` values of the `input`, it causes the cursor style of the
+ * decrement button to change from `default` to `text`.
+ */
+
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+/**
+ * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
+ * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
+ * (include `-moz` to future-proof).
+ */
+
+input[type="search"] {
+ -webkit-appearance: textfield; /* 1 */
+ -moz-box-sizing: content-box;
+ -webkit-box-sizing: content-box; /* 2 */
+ box-sizing: content-box;
+}
+
+/**
+ * Remove inner padding and search cancel button in Safari and Chrome on OS X.
+ * Safari (but not Chrome) clips the cancel button when the search input has
+ * padding (and `textfield` appearance).
+ */
+
+input[type="search"]::-webkit-search-cancel-button,
+input[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+
+/**
+ * Define consistent border, margin, and padding.
+ */
+
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
+}
+
+/**
+ * 1. Correct `color` not being inherited in IE 8/9/10/11.
+ * 2. Remove padding so people aren't caught out if they zero out fieldsets.
+ */
+
+legend {
+ border: 0; /* 1 */
+ padding: 0; /* 2 */
+}
+
+/**
+ * Remove default vertical scrollbar in IE 8/9/10/11.
+ */
+
+textarea {
+ overflow: auto;
+}
+
+/**
+ * Don't inherit the `font-weight` (applied by a rule above).
+ * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
+ */
+
+optgroup {
+ font-weight: bold;
+}
+
+/* Tables
+ ========================================================================== */
+
+/**
+ * Remove most spacing between table cells.
+ */
+
+table {
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+td,
+th {
+ padding: 0;
+}
diff --git a/templates/edit.tmpl b/templates/edit.tmpl
new file mode 100644
index 00000000..c335461f
--- /dev/null
+++ b/templates/edit.tmpl
@@ -0,0 +1,5 @@
+{{#HEADER#}}
+
+
+
+{{#FOOTER#}}
diff --git a/templates/edit_form.tpl b/templates/edit_form.tpl
deleted file mode 100644
index f785092e..00000000
--- a/templates/edit_form.tpl
+++ /dev/null
@@ -1,7 +0,0 @@
-{{ define "Head" }}
-{{ template "head" }}
-{{ end }}
-
-{{define "Body"}}
-{{ .Content }}
-{{ end }}
diff --git a/templates/footer.tmpl b/templates/footer.tmpl
new file mode 100644
index 00000000..0399fdf2
--- /dev/null
+++ b/templates/footer.tmpl
@@ -0,0 +1,5 @@
+
+