pull/20/head
Henrique Dias 2015-09-14 10:46:31 +01:00
parent 788218e115
commit e9d507fec3
9 changed files with 173 additions and 90 deletions

View File

@ -2,6 +2,7 @@ package edit
import (
"io/ioutil"
"log"
"net/http"
"os"
"strings"
@ -24,18 +25,21 @@ func Execute(w http.ResponseWriter, r *http.Request) (int, error) {
err := ioutil.WriteFile(filename, []byte(r.Form["content"][0]), 0666)
if err != nil {
log.Print(err)
return 500, err
}
commands.Execute()
} else {
if _, err := os.Stat(filename); os.IsNotExist(err) {
log.Print(err)
return 404, nil
}
file, err := ioutil.ReadFile(filename)
if err != nil {
log.Print(err)
return 500, err
}

View File

@ -2,52 +2,19 @@ package page
import (
"html/template"
"log"
"net/http"
"reflect"
"strings"
"unicode"
"github.com/hacdias/caddy-hugo/assets"
"github.com/hacdias/caddy-hugo/utils"
)
const (
templateExtension = ".tmpl"
headerMark = "{{#HEADER#}}"
footerMark = "{{#FOOTER#}}"
)
var funcMap = template.FuncMap{
"splitCapitalize": splitCapitalize,
"isMap": isMap,
}
// TODO: utilspackage
func isMap(sth interface{}) bool {
return reflect.ValueOf(sth).Kind() == reflect.Map
}
// TODO: utils package
func splitCapitalize(name string) string {
var words []string
l := 0
for s := name; s != ""; s = s[l:] {
l = strings.IndexFunc(s[1:], unicode.IsUpper) + 1
if l <= 0 {
l = len(s)
}
words = append(words, s[:l])
}
name = ""
for _, element := range words {
name += element + " "
}
name = strings.ToLower(name[:len(name)-1])
name = strings.ToUpper(string(name[0])) + name[1:len(name)]
return name
"splitCapitalize": utils.SplitCapitalize,
}
// Page type
@ -58,38 +25,34 @@ type Page struct {
// Render the page
func (p *Page) Render(name string, w http.ResponseWriter) (int, error) {
rawHeader, err := assets.Asset("templates/header" + templateExtension)
base, err := assets.Asset("templates/base" + templateExtension)
if err != nil {
log.Print(err)
return 500, err
}
header := string(rawHeader)
rawFooter, err := assets.Asset("templates/footer" + templateExtension)
page, err := assets.Asset("templates/" + name + templateExtension)
if err != nil {
log.Print(err)
return 500, err
}
footer := string(rawFooter)
rawPage, err := assets.Asset("templates/" + name + templateExtension)
tpl, err := template.New("base").Funcs(funcMap).Parse(string(base))
if err != nil {
log.Print(err)
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").Funcs(funcMap).Parse(page)
tpl, err = tpl.Parse(string(page))
if err != nil {
log.Print(err)
return 500, err
}
tpl.Execute(w, p)
tpl.ExecuteTemplate(w, "base", p)
return 200, nil
}

View File

@ -4,11 +4,18 @@ import (
"io/ioutil"
"net/http"
"os"
"sort"
"github.com/hacdias/caddy-hugo/page"
"github.com/hacdias/caddy-hugo/utils"
"github.com/spf13/hugo/parser"
)
type settings struct {
Settings interface{}
Keys []string
}
// Execute the page
func Execute(w http.ResponseWriter, r *http.Request) (int, error) {
if r.Method == "POST" {
@ -27,9 +34,14 @@ func Execute(w http.ResponseWriter, r *http.Request) (int, error) {
return 500, err
}
// configIndex := getConfigNames(config)
cnf := new(settings)
cnf.Settings = getConfigNames(config, "")
page := new(page.Page)
page.Title = "settings"
page.Body = config
page.Title = "Settings"
page.Body = cnf
return page.Render("settings", w)
}
@ -54,21 +66,6 @@ func getConfigFrontMatter() string {
return frontmatter
}
func getConfig(frontmatter string) (interface{}, error) {
content := getConfigFileContent(frontmatter)
switch frontmatter {
case "yaml":
return parser.HandleYAMLMetaData(content)
case "json":
return parser.HandleJSONMetaData(content)
case "toml":
return parser.HandleTOMLMetaData(content)
}
return []string{}, nil
}
func getConfigFileContent(frontmatter string) []byte {
file, err := ioutil.ReadFile("config." + frontmatter)
@ -79,3 +76,66 @@ func getConfigFileContent(frontmatter string) []byte {
return file
}
// make it generic to frontmatter. everything bellow -> new file
func getConfig(frontmatter string) (interface{}, error) {
content := getConfigFileContent(frontmatter)
// config := []string{}
// get the config into a map
if frontmatter == "yaml" {
return parser.HandleYAMLMetaData(content)
} else if frontmatter == "json" {
return parser.HandleJSONMetaData(content)
} else if frontmatter == "toml" {
return parser.HandleTOMLMetaData(content)
}
return []string{}, nil
}
type conf struct {
Name string
Master string
Content interface{}
SubContent bool
}
func getConfigNames(config interface{}, master string) interface{} {
var mapsNames []string
var stringsNames []string
for index, element := range config.(map[string]interface{}) {
if utils.IsMap(element) {
mapsNames = append(mapsNames, index)
} else {
stringsNames = append(stringsNames, index)
}
}
sort.Strings(mapsNames)
sort.Strings(stringsNames)
names := append(stringsNames, mapsNames...)
settings := make([]interface{}, len(names))
for index := range names {
c := new(conf)
c.Name = names[index]
c.Master = master
c.SubContent = false
i := config.(map[string]interface{})[names[index]]
if utils.IsMap(i) {
c.Content = getConfigNames(i, c.Name)
c.SubContent = true
} else {
c.Content = i
}
settings[index] = c
}
return settings
}

View File

@ -30,3 +30,7 @@ textarea {
border: 0;
font-family: inherit;
}
.block {
margin: 1em 0;
}

View File

@ -20,3 +20,9 @@
<header class="site-header">
Admin
</header>
{{ template "content" . }}
<footer></footer>
</body>
</html>

View File

@ -1,4 +1,4 @@
{{#HEADER#}}
{{ define "content" }}
{{ with .Body }}
<div class="content">
@ -13,4 +13,4 @@
</div>
{{ end }}
{{#FOOTER#}}
{{ end }}

View File

@ -1,5 +0,0 @@
<footer>
</footer>
</body>
</html>

View File

@ -1,4 +1,18 @@
{{#HEADER#}}
{{ define "optsLoop" }}
{{ range $key, $value := . }}
{{ if $value.SubContent }}
<h2>{{ splitCapitalize $value.Name }}</h2>
{{ template "optsLoop" $value.Content }}
{{ else}}
<label for="{{ $value.Master }}_{{ $value.Name }}">{{ splitCapitalize $value.Name }}</label>
<input name="{{ $value.Master }}_{{ $value.Name }}" id="{{ $value.Master }}_{{ $value.Name }}" value="{{ $value.Content }}"></input><br>
{{ end }}
{{ end }}
{{ end }}
{{ define "content" }}
{{ with .Body }}
<div class="content">
@ -6,25 +20,11 @@
<h1>Settings</h1>
<form>
{{ range $key, $value := . }}
{{ if isMap $value }}
<h2>{{ splitCapitalize $key }}</h2>
<div id="{{ $key }}">
<!-- call this range again -->
</div>
{{ else }}
<label for="{{ $key }}">{{ splitCapitalize $key }}</label>
<input name="{{ $key }}" id="{{ $key }}" value="{{ $value }}"></input><br>
{{ end }}
{{ end }}
{{ template "optsLoop" .Settings }}
</form>
</div>
{{ end }}
{{#FOOTER#}}
{{ end }}

51
utils/utils.go Normal file
View File

@ -0,0 +1,51 @@
package utils
import (
"errors"
"reflect"
"strings"
"unicode"
)
// Dict allows to send more than one variable into a template
func Dict(values ...interface{}) (map[string]interface{}, error) {
if len(values)%2 != 0 {
return nil, errors.New("invalid dict call")
}
dict := make(map[string]interface{}, len(values)/2)
for i := 0; i < len(values); i += 2 {
key, ok := values[i].(string)
if !ok {
return nil, errors.New("dict keys must be strings")
}
dict[key] = values[i+1]
}
return dict, nil
}
func IsMap(sth interface{}) bool {
return reflect.ValueOf(sth).Kind() == reflect.Map
}
func SplitCapitalize(name string) string {
var words []string
l := 0
for s := name; s != ""; s = s[l:] {
l = strings.IndexFunc(s[1:], unicode.IsUpper) + 1
if l <= 0 {
l = len(s)
}
words = append(words, s[:l])
}
name = ""
for _, element := range words {
name += element + " "
}
name = strings.ToLower(name[:len(name)-1])
name = strings.ToUpper(string(name[0])) + name[1:len(name)]
return name
}