From 650bdc2fd6f064897c1c99b6677063c36d5eb7ee Mon Sep 17 00:00:00 2001 From: Sebastian Frank Date: Wed, 27 Feb 2019 17:33:26 +0100 Subject: [PATCH] reorganized code --- config/global.go | 42 +++++++ helper/logger.go | 52 +++++++++ helper/render.go | 67 +++++++++++ helper/template_functions.go | 20 +++- main.go | 141 ++++------------------- website/templates/base_blog.html | 2 + website/templates/base_blog_details.html | 9 ++ 7 files changed, 215 insertions(+), 118 deletions(-) create mode 100644 config/global.go create mode 100644 helper/logger.go create mode 100644 helper/render.go create mode 100644 website/templates/base_blog_details.html diff --git a/config/global.go b/config/global.go new file mode 100644 index 0000000..2a40a94 --- /dev/null +++ b/config/global.go @@ -0,0 +1,42 @@ +package config + +import ( + "io/ioutil" + + "gopkg.in/yaml.v2" +) + +// GlobalConfig is config which is used only once in root dir +type GlobalConfig struct { + Webserver struct { + Type string `yaml:"Type"` + } `yaml:"Webserver"` + + Assets struct { + FromPath string `yaml:"FromPath"` + ToPath string `yaml:"ToPath"` + Action string `yaml:"Action"` + FixTemplate struct { + Find string `yaml:"Find"` + Replace string `yaml:"Replace"` + } `yaml:"FixTemplate"` + } `yaml:"Assets"` + + OtherFiles struct { + Action string `yaml:"Action"` + } `yaml:"OtherFiles"` +} + +var Config = new(GlobalConfig) + +func ReadGlobalConfig(filename string) error { + data, err := ioutil.ReadFile(filename) + if err != nil { + return err + } + err = yaml.Unmarshal(data, Config) + if err != nil { + return err + } + return nil +} diff --git a/helper/logger.go b/helper/logger.go new file mode 100644 index 0000000..f6f805a --- /dev/null +++ b/helper/logger.go @@ -0,0 +1,52 @@ +package helper + +import ( + "os" + + "github.com/davecgh/go-spew/spew" + "github.com/op/go-logging" +) + +// Log is global logger +var Log = logging.MustGetLogger("myLogger") + +// ConfigureLogger sets logger backend and level +func ConfigureLogger(level string) { + logBackend := logging.NewLogBackend(os.Stderr, "", 0) + logBackendFormatter := logging.NewBackendFormatter(logBackend, logging.MustStringFormatter( + `%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`, + )) + logBackendLeveled := logging.AddModuleLevel(logBackendFormatter) + logBackendLevel := logging.INFO + switch level { + case "debug": + logBackendLevel = logging.DEBUG + break + + case "info": + logBackendLevel = logging.INFO + break + + case "notice": + logBackendLevel = logging.NOTICE + break + + case "warning": + logBackendLevel = logging.WARNING + break + + case "error": + logBackendLevel = logging.ERROR + break + + } + logBackendLeveled.SetLevel(logBackendLevel, "") + logging.SetBackend(logBackendLeveled) +} + +func init() { + spew.Config.DisablePointerAddresses = true + spew.Config.DisableCapacities = true + spew.Config.DisableMethods = true + spew.Config.DisablePointerMethods = true +} diff --git a/helper/render.go b/helper/render.go new file mode 100644 index 0000000..726ed67 --- /dev/null +++ b/helper/render.go @@ -0,0 +1,67 @@ +package helper + +import ( + "log" + "path" + "regexp" + "strings" + + "gitbase.de/apairon/mark2web/config" + "github.com/flosch/pongo2" +) + +var templateCache = make(map[string]*pongo2.Template) +var currentContext map[string]interface{} +var templateDir string + +func BackToRoot(curNavPath string) string { + tmpPath := "" + if curNavPath != "" { + for i := strings.Count(curNavPath, "/") + 1; i > 0; i-- { + tmpPath += "../" + } + } + return tmpPath +} + +// SetTemplateDir sets base directory for searching template files +func SetTemplateDir(dir string) { + templateDir = dir +} + +// RenderTemplate renders a pongo2 template with context +func RenderTemplate(filename string, ctx map[string]interface{}) (string, error) { + currentContext = ctx + templateFile := templateDir + "/" + filename + template := templateCache[templateFile] + if template == nil { + var err error + if template, err = pongo2.FromFile(templateFile); err != nil { + log.Panicf("could not parse template '%s': %s", templateFile, err) + } else { + templateCache[templateFile] = template + } + } + + return template.Execute(ctx) +} + +func FixAssetsPath(str, curNavPath string) string { + if find := config.Config.Assets.FixTemplate.Find; find != "" { + Log.Debugf("fixing assets paths for path '%s'", curNavPath) + repl := config.Config.Assets.FixTemplate.Replace + toPath := config.Config.Assets.ToPath + + bToRoot := BackToRoot(curNavPath) + regex, err := regexp.Compile(find) + if err != nil { + log.Panicf("could not compile regexp '%s' for assets path: %s", find, err) + } + repl = bToRoot + toPath + "/" + repl + repl = path.Clean(repl) + "/" + Log.Debugf("new assets paths: %s", repl) + return regex.ReplaceAllString(str, repl) + } else { + return str + } +} diff --git a/helper/template_functions.go b/helper/template_functions.go index 0b8dc3a..b181b19 100644 --- a/helper/template_functions.go +++ b/helper/template_functions.go @@ -11,8 +11,8 @@ import ( "github.com/flosch/pongo2" ) -// Request will make a web request and returns map[string]interface form pongo2 -func Request(url *pongo2.Value, args ...*pongo2.Value) *pongo2.Value { +// RequestFn will make a web request and returns map[string]interface form pongo2 +func RequestFn(url *pongo2.Value, args ...*pongo2.Value) *pongo2.Value { u := url.String() fmt.Printf("request GET %s\n", u) @@ -49,3 +49,19 @@ func Request(url *pongo2.Value, args ...*pongo2.Value) *pongo2.Value { return pongo2.AsValue(jsonMap) } + +// RenderFn renders a pongo2 template with additional context +func RenderFn(templateFilename, outDir, subCtxName, ctx *pongo2.Value) *pongo2.Value { + currentContext[subCtxName.String()] = ctx + result, err := RenderTemplate(templateFilename.String(), currentContext) + if err != nil { + panic(err) + } + + result = FixAssetsPath( + result, + currentContext["CurrentPath"].(string), + ) + spew.Dump(result) + return pongo2.AsValue(nil) +} diff --git a/main.go b/main.go index 4d148bd..d6040b8 100644 --- a/main.go +++ b/main.go @@ -13,12 +13,12 @@ import ( "github.com/imdario/mergo" + "gitbase.de/apairon/mark2web/config" "gitbase.de/apairon/mark2web/helper" "github.com/Depado/bfchroma" "github.com/davecgh/go-spew/spew" "github.com/flosch/pongo2" "github.com/gosimple/slug" - "github.com/op/go-logging" cpy "github.com/otiai10/copy" "gopkg.in/russross/blackfriday.v2" "gopkg.in/yaml.v2" @@ -33,36 +33,11 @@ var ( BuildTime = "UNKNOWN" ) -var log = logging.MustGetLogger("myLogger") +var log = helper.Log var inDir *string var outDir *string -var templateCache = make(map[string]*pongo2.Template) - -// GlobalConfig is config which is used only once in root dir -type GlobalConfig struct { - Webserver struct { - Type string `yaml:"Type"` - } `yaml:"Webserver"` - - Assets struct { - FromPath string `yaml:"FromPath"` - ToPath string `yaml:"ToPath"` - Action string `yaml:"Action"` - FixTemplate struct { - Find string `yaml:"Find"` - Replace string `yaml:"Replace"` - } `yaml:"FixTemplate"` - } `yaml:"Assets"` - - OtherFiles struct { - Action string `yaml:"Action"` - } `yaml:"OtherFiles"` -} - -var globalConfig = new(GlobalConfig) - // ThisPathConfig is struct for This in paths yaml type ThisPathConfig struct { Navname *string `yaml:"Navname"` @@ -144,16 +119,6 @@ func merge(dst, src interface{}) error { return mergo.Merge(dst, src, mergo.WithTransformers(ptrTransformer{})) } -func backToRoot(curNavPath string) string { - tmpPath := "" - if curNavPath != "" { - for i := strings.Count(curNavPath, "/") + 1; i > 0; i-- { - tmpPath += "../" - } - } - return tmpPath -} - func readContentDir(inBase string, outBase string, dir string, conf *PathConfig, tree *PathConfigTree) { inPath := inBase if dir != "" { @@ -333,7 +298,7 @@ func buildNavigation(conf *PathConfigTree, curNavMap *map[string]*navElement, cu if activeNav != "" && activeNav != "/" { // calculate relative path - bToRoot := backToRoot(activeNav) + bToRoot := helper.BackToRoot(activeNav) navEl.GoTo = bToRoot + navEl.GoTo navEl.GoTo = path.Clean(navEl.GoTo) } @@ -377,11 +342,11 @@ func processContent(conf *PathConfigTree) { if goTo != nil && *goTo != "" { goToFixed := *goTo if strings.HasPrefix(goToFixed, "/") { - goToFixed = backToRoot(curNavPath) + goToFixed + goToFixed = helper.BackToRoot(curNavPath) + goToFixed } goToFixed = path.Clean(goToFixed) - switch globalConfig.Webserver.Type { + switch config.Config.Webserver.Type { case "apache": htaccessFile := conf.OutputPath + "/.htaccess" log.Noticef("writing '%s' with redirect to: %s", htaccessFile, goToFixed) @@ -512,18 +477,6 @@ RewriteRule ^$ %{REQUEST_URI}`+goToFixed+`/ [R,L] htmlParts = append(htmlParts, pongo2.AsSafeValue(string(blackfriday.Run([]byte(iPart), options...)))) } - log.Debugf("rendering template '%s' for '%s'", *newConfig.Template, outFile) - templateFile := *inDir + "/templates/" + *newConfig.Template - template := templateCache[templateFile] - if template == nil { - var err error - if template, err = pongo2.FromFile(templateFile); err != nil { - log.Panicf("could not parse template '%s': %s", templateFile, err) - } else { - templateCache[templateFile] = template - } - } - // build navigation navMap := make(map[string]*navElement) navSlice := make([]*navElement, 0) @@ -540,28 +493,21 @@ RewriteRule ^$ %{REQUEST_URI}`+goToFixed+`/ [R,L] ctx["NavActive"] = navActive ctx["Body"] = pongo2.AsSafeValue(string(html)) ctx["BodyParts"] = htmlParts + ctx["AssetsPath"] = config.Config.Assets.ToPath + ctx["CurrentPath"] = curNavPath // register functions - ctx["fnRequest"] = helper.Request + ctx["fnRequest"] = helper.RequestFn + ctx["fnRender"] = helper.RenderFn - result, err := template.Execute(ctx) + log.Debugf("rendering template '%s' for '%s'", *newConfig.Template, outFile) + templateFilename := *newConfig.Template + result, err := helper.RenderTemplate(*newConfig.Template, ctx) if err != nil { - log.Panicf("could not execute template '%s' for input file '%s': %s", templateFile, inFile, err) + log.Panicf("could not execute template '%s' for input file '%s': %s", templateFilename, inFile, err) } - if find := globalConfig.Assets.FixTemplate.Find; find != "" { - log.Debugf("fixing assets paths in '%s' for '%s'", templateFile, inFile) - bToRoot := backToRoot(curNavPath) - regex, err := regexp.Compile(find) - if err != nil { - log.Panicf("could not compile regexp '%s' for assets path: %s", find, err) - } - repl := globalConfig.Assets.FixTemplate.Replace - repl = bToRoot + globalConfig.Assets.ToPath + "/" + repl - repl = path.Clean(repl) + "/" - log.Debugf("new assets paths: %s", repl) - result = regex.ReplaceAllString(result, repl) - } + result = helper.FixAssetsPath(result, curNavPath) log.Noticef("writing to output file: %s", outFile) err = ioutil.WriteFile(outFile, []byte(result), 0644) @@ -575,7 +521,7 @@ RewriteRule ^$ %{REQUEST_URI}`+goToFixed+`/ [R,L] // process other files, copy... for _, file := range conf.OtherFiles { - switch globalConfig.OtherFiles.Action { + switch config.Config.OtherFiles.Action { case "copy": from := conf.InputPath + "/" + file to := conf.OutputPath + "/" + file @@ -593,10 +539,10 @@ RewriteRule ^$ %{REQUEST_URI}`+goToFixed+`/ [R,L] } func processAssets() { - switch globalConfig.Assets.Action { + switch config.Config.Assets.Action { case "copy": - from := globalConfig.Assets.FromPath - to := globalConfig.Assets.ToPath + from := config.Config.Assets.FromPath + to := config.Config.Assets.ToPath if !strings.HasPrefix(from, "/") { from = *inDir + "/" + from } @@ -612,11 +558,6 @@ func processAssets() { } func main() { - spew.Config.DisablePointerAddresses = true - spew.Config.DisableCapacities = true - spew.Config.DisableMethods = true - spew.Config.DisablePointerMethods = true - inDir = flag.String("in", "./", "input directory") outDir = flag.String("out", "html", "output directory") createOutDir := flag.Bool("create", false, "create output directory if not existing") @@ -633,38 +574,11 @@ func main() { os.Exit(0) } - logBackend := logging.NewLogBackend(os.Stderr, "", 0) - logBackendFormatter := logging.NewBackendFormatter(logBackend, logging.MustStringFormatter( - `%{color}%{time:15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}`, - )) - logBackendLeveled := logging.AddModuleLevel(logBackendFormatter) - logBackendLevel := logging.INFO + level := "info" if logLevel != nil { - switch *logLevel { - case "debug": - logBackendLevel = logging.DEBUG - break - - case "info": - logBackendLevel = logging.INFO - break - - case "notice": - logBackendLevel = logging.NOTICE - break - - case "warning": - logBackendLevel = logging.WARNING - break - - case "error": - logBackendLevel = logging.ERROR - break - - } + level = *logLevel } - logBackendLeveled.SetLevel(logBackendLevel, "") - logging.SetBackend(logBackendLeveled) + helper.ConfigureLogger(level) if inDir == nil || *inDir == "" { log.Panic("input directory not specified") @@ -701,17 +615,11 @@ func main() { } log.Debug("reading global config...") - p := *inDir + "/config.yml" - data, err := ioutil.ReadFile(p) + configFilename := *inDir + "/config.yml" + err := config.ReadGlobalConfig(configFilename) if err != nil { - log.Panicf("could not read file '%s': %s", p, err) + log.Panicf("could not read file '%s': %s", configFilename, err) } - err = yaml.Unmarshal(data, globalConfig) - if err != nil { - log.Panicf("could not parse YAML file '%s': %s", p, err) - } - - log.Debug(spew.Sdump(globalConfig)) log.Debugf("reading input directory %s", *inDir) @@ -745,6 +653,7 @@ func main() { //spew.Dump(navMap) + helper.SetTemplateDir(*inDir + "/templates") processContent(contentConfig) processAssets() diff --git a/website/templates/base_blog.html b/website/templates/base_blog.html index dfd102f..ef21eea 100644 --- a/website/templates/base_blog.html +++ b/website/templates/base_blog.html @@ -10,6 +10,7 @@ {{ e.teaser|markdown }} {% if e.body %} mehr lesen + {{ fnRender("base_blog_details.html", e.title, "details", e) }} {% endif %} {% endfor %} {% endblock part0 %} @@ -26,6 +27,7 @@ {{ e.teaser|markdown }} {% if e.body %} mehr lesen + {{ fnRender("base_blog_details.html", e.title, "details", e) }} {% endif %} {% endfor %} {% endblock part1 %} diff --git a/website/templates/base_blog_details.html b/website/templates/base_blog_details.html new file mode 100644 index 0000000..0a3589b --- /dev/null +++ b/website/templates/base_blog_details.html @@ -0,0 +1,9 @@ +{% extends 'base.html' %} + +{% block part0 %} +

{{ details.title }}

+{% endblock part0 %} + +{% block part1 %} + +{% endblock part1 %} \ No newline at end of file