json and dump filter
This commit is contained in:
parent
a2eaa3f4b4
commit
2f2454ee54
config
helper
website
@ -1,11 +1,56 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/imdario/mergo"
|
"github.com/imdario/mergo"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MapString is a map[string]interface{} which always unmarsahls yaml to map[string]interface{}
|
||||||
|
type MapString map[string]interface{}
|
||||||
|
|
||||||
|
// UnmarshalYAML handles all maps as map[string]interface{} for later JSON
|
||||||
|
// see https://github.com/elastic/beats/blob/6435194af9f42cbf778ca0a1a92276caf41a0da8/libbeat/common/mapstr.go
|
||||||
|
func (ms *MapString) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||||
|
var result map[interface{}]interface{}
|
||||||
|
err := unmarshal(&result)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*ms = cleanUpInterfaceMap(result)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanUpInterfaceArray(in []interface{}) []interface{} {
|
||||||
|
result := make([]interface{}, len(in))
|
||||||
|
for i, v := range in {
|
||||||
|
result[i] = cleanUpMapValue(v)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanUpInterfaceMap(in map[interface{}]interface{}) MapString {
|
||||||
|
result := make(MapString)
|
||||||
|
for k, v := range in {
|
||||||
|
result[fmt.Sprintf("%v", k)] = cleanUpMapValue(v)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanUpMapValue(v interface{}) interface{} {
|
||||||
|
switch v := v.(type) {
|
||||||
|
case []interface{}:
|
||||||
|
return cleanUpInterfaceArray(v)
|
||||||
|
case map[interface{}]interface{}:
|
||||||
|
return cleanUpInterfaceMap(v)
|
||||||
|
case string:
|
||||||
|
return v
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("%v", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CollectionConfig describes a collection
|
// CollectionConfig describes a collection
|
||||||
type CollectionConfig struct {
|
type CollectionConfig struct {
|
||||||
Name *string `yaml:"Name"`
|
Name *string `yaml:"Name"`
|
||||||
@ -26,7 +71,7 @@ type ThisPathConfig struct {
|
|||||||
Navname *string `yaml:"Navname"`
|
Navname *string `yaml:"Navname"`
|
||||||
GoTo *string `yaml:"GoTo"`
|
GoTo *string `yaml:"GoTo"`
|
||||||
Collections []*CollectionConfig `yaml:"Collections"`
|
Collections []*CollectionConfig `yaml:"Collections"`
|
||||||
Data interface{} `yaml:"Data"`
|
Data MapString `yaml:"Data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexConfig describes index input and output file
|
// IndexConfig describes index input and output file
|
||||||
@ -85,7 +130,7 @@ type PathConfig struct {
|
|||||||
Markdown *MarkdownConfig `yaml:"Markdown"`
|
Markdown *MarkdownConfig `yaml:"Markdown"`
|
||||||
Imaging *ImagingConfig `yaml:"Imaging"`
|
Imaging *ImagingConfig `yaml:"Imaging"`
|
||||||
|
|
||||||
Data map[string]interface{} `yaml:"Data"`
|
Data MapString `yaml:"Data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PathConfigTree is complete config tree of content dir
|
// PathConfigTree is complete config tree of content dir
|
||||||
@ -94,7 +139,7 @@ type PathConfigTree struct {
|
|||||||
OutputPath string
|
OutputPath string
|
||||||
Hidden bool // for collections which are not part of the navigation
|
Hidden bool // for collections which are not part of the navigation
|
||||||
|
|
||||||
ColMap map[string]interface{}
|
ColMap MapString
|
||||||
|
|
||||||
InputFiles []string
|
InputFiles []string
|
||||||
OtherFiles []string
|
OtherFiles []string
|
||||||
|
@ -19,8 +19,8 @@ import (
|
|||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newContext() map[string]interface{} {
|
func newContext() pongo2.Context {
|
||||||
return map[string]interface{}{
|
return pongo2.Context{
|
||||||
"fnRequest": RequestFn,
|
"fnRequest": RequestFn,
|
||||||
"fnRender": RenderFn,
|
"fnRender": RenderFn,
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ func fillNodeConfig(node *config.PathConfigTree, inBase, outBase, dir string, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
if node.ColMap == nil {
|
if node.ColMap == nil {
|
||||||
node.ColMap = make(map[string]interface{})
|
node.ColMap = make(config.MapString)
|
||||||
}
|
}
|
||||||
ctx := newContext()
|
ctx := newContext()
|
||||||
jsonStr, err := pongo2.RenderTemplateString(*colConfig.EntriesJSON, ctx)
|
jsonStr, err := pongo2.RenderTemplateString(*colConfig.EntriesJSON, ctx)
|
||||||
@ -114,7 +114,7 @@ func fillNodeConfig(node *config.PathConfigTree, inBase, outBase, dir string, co
|
|||||||
Log.Panicf("invalid template string in '%s': %s", inPath, err)
|
Log.Panicf("invalid template string in '%s': %s", inPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var colSlice []map[string]interface{}
|
var colSlice []config.MapString
|
||||||
err = json.Unmarshal([]byte(jsonStr), &colSlice)
|
err = json.Unmarshal([]byte(jsonStr), &colSlice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Log.Panicf("invalid JSON in EntriesJSON in '%s': %s", inPath, err)
|
Log.Panicf("invalid JSON in EntriesJSON in '%s': %s", inPath, err)
|
||||||
@ -130,12 +130,12 @@ func fillNodeConfig(node *config.PathConfigTree, inBase, outBase, dir string, co
|
|||||||
|
|
||||||
// build navigation with detail sites
|
// build navigation with detail sites
|
||||||
for _, colEl := range colSlice {
|
for _, colEl := range colSlice {
|
||||||
ctxE := make(map[string]interface{})
|
ctxE := make(pongo2.Context)
|
||||||
err := config.Merge(&ctxE, ctx)
|
err := config.Merge(&ctxE, ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Log.Panicf("could not merge context in '%s': %s", inPath, err)
|
Log.Panicf("could not merge context in '%s': %s", inPath, err)
|
||||||
}
|
}
|
||||||
err = config.Merge(&ctxE, colEl)
|
err = config.Merge(&ctxE, pongo2.Context(colEl))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Log.Panicf("could not merge context in '%s': %s", inPath, err)
|
Log.Panicf("could not merge context in '%s': %s", inPath, err)
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ type NavElement struct {
|
|||||||
GoTo string
|
GoTo string
|
||||||
Active bool
|
Active bool
|
||||||
|
|
||||||
ColMap map[string]interface{}
|
ColMap config.MapString
|
||||||
|
|
||||||
Data interface{}
|
Data interface{}
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ func BuildNavigation(conf *config.PathConfigTree, curNavMap *map[string]*NavElem
|
|||||||
navEl.GoTo = path.Clean(navEl.GoTo)
|
navEl.GoTo = path.Clean(navEl.GoTo)
|
||||||
}
|
}
|
||||||
|
|
||||||
(*curNavMap)[navEl.Navname] = &navEl
|
(*curNavMap)[path.Base(el.OutputPath)] = &navEl
|
||||||
if curNavSlice != nil {
|
if curNavSlice != nil {
|
||||||
*curNavSlice = append(*curNavSlice, &navEl)
|
*curNavSlice = append(*curNavSlice, &navEl)
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var templateCache = make(map[string]*pongo2.Template)
|
var templateCache = make(map[string]*pongo2.Template)
|
||||||
var currentContext *map[string]interface{}
|
var currentContext *pongo2.Context
|
||||||
var currentTreeNodeConfig *config.PathConfigTree
|
var currentTreeNodeConfig *config.PathConfigTree
|
||||||
var currentPathConfig *config.PathConfig
|
var currentPathConfig *config.PathConfig
|
||||||
var templateDir string
|
var templateDir string
|
||||||
@ -63,7 +63,7 @@ func SetTemplateDir(dir string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RenderTemplate renders a pongo2 template with context
|
// RenderTemplate renders a pongo2 template with context
|
||||||
func RenderTemplate(filename string, treeNodeConfig *config.PathConfigTree, pathConfig *config.PathConfig, ctx *map[string]interface{}) (string, error) {
|
func RenderTemplate(filename string, treeNodeConfig *config.PathConfigTree, pathConfig *config.PathConfig, ctx *pongo2.Context) (string, error) {
|
||||||
currentContext = ctx
|
currentContext = ctx
|
||||||
currentTreeNodeConfig = treeNodeConfig
|
currentTreeNodeConfig = treeNodeConfig
|
||||||
currentPathConfig = pathConfig
|
currentPathConfig = pathConfig
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gitbase.de/apairon/mark2web/config"
|
"gitbase.de/apairon/mark2web/config"
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/ddliu/motto"
|
"github.com/ddliu/motto"
|
||||||
"github.com/disintegration/imaging"
|
"github.com/disintegration/imaging"
|
||||||
"github.com/flosch/pongo2"
|
"github.com/flosch/pongo2"
|
||||||
@ -32,6 +33,7 @@ func init() {
|
|||||||
"image_process": ImageProcessFilter,
|
"image_process": ImageProcessFilter,
|
||||||
"relative_path": RelativePathFilter,
|
"relative_path": RelativePathFilter,
|
||||||
"json": JSONFilter,
|
"json": JSONFilter,
|
||||||
|
"dump": DumpFilter,
|
||||||
}
|
}
|
||||||
for name, fn := range newFilters {
|
for name, fn := range newFilters {
|
||||||
err := pongo2.RegisterFilter(name, fn)
|
err := pongo2.RegisterFilter(name, fn)
|
||||||
@ -41,9 +43,29 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DumpFilter is a pongo2 filter, which returns a spew.Dump of the input
|
||||||
|
func DumpFilter(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) {
|
||||||
|
dumpString := spew.Sdump(in.Interface())
|
||||||
|
return pongo2.AsValue(string(dumpString)), nil
|
||||||
|
}
|
||||||
|
|
||||||
// JSONFilter is a pongo2 filter, which returns a json string of the input
|
// JSONFilter is a pongo2 filter, which returns a json string of the input
|
||||||
func JSONFilter(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) {
|
func JSONFilter(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) {
|
||||||
jsonString, err := json.Marshal(in.Interface())
|
pretty := false
|
||||||
|
for _, s := range strings.Split(param.String(), ",") {
|
||||||
|
switch s {
|
||||||
|
case "pretty":
|
||||||
|
pretty = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
var jsonBytes []byte
|
||||||
|
if pretty {
|
||||||
|
jsonBytes, err = json.MarshalIndent(in.Interface(), "", " ")
|
||||||
|
|
||||||
|
} else {
|
||||||
|
jsonBytes, err = json.Marshal(in.Interface())
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &pongo2.Error{
|
return nil, &pongo2.Error{
|
||||||
Sender: "filter:json",
|
Sender: "filter:json",
|
||||||
@ -51,7 +73,7 @@ func JSONFilter(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.E
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pongo2.AsSafeValue(string(jsonString)), nil
|
return pongo2.AsSafeValue(string(jsonBytes)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkdownFilter is a pongo2 filter, which converts markdown to html
|
// MarkdownFilter is a pongo2 filter, which converts markdown to html
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/flosch/pongo2"
|
"github.com/flosch/pongo2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func jsonWebRequest(url string) map[string]interface{} {
|
func jsonWebRequest(url string) config.MapString {
|
||||||
Log.Noticef("requesting url via GET %s", url)
|
Log.Noticef("requesting url via GET %s", url)
|
||||||
|
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
@ -38,7 +38,7 @@ func jsonWebRequest(url string) map[string]interface{} {
|
|||||||
Log.Panicf("is not json '%s' from url '%s'", contentType, url)
|
Log.Panicf("is not json '%s' from url '%s'", contentType, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonMap := make(map[string]interface{})
|
jsonMap := make(config.MapString)
|
||||||
err = json.Unmarshal(body, &jsonMap)
|
err = json.Unmarshal(body, &jsonMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Log.Panicf("could not read json from '%s': %s", url, err)
|
Log.Panicf("could not read json from '%s': %s", url, err)
|
||||||
@ -69,7 +69,7 @@ func add2Nav(currentNode *config.PathConfigTree, pathConfig *config.PathConfig,
|
|||||||
}
|
}
|
||||||
if dataMapKey != "" {
|
if dataMapKey != "" {
|
||||||
if newNodeConfig.Config.Data == nil {
|
if newNodeConfig.Config.Data == nil {
|
||||||
newNodeConfig.Config.Data = make(map[string]interface{})
|
newNodeConfig.Config.Data = make(config.MapString)
|
||||||
}
|
}
|
||||||
// as submap in Data
|
// as submap in Data
|
||||||
newNodeConfig.Config.Data[dataMapKey] = ctx
|
newNodeConfig.Config.Data[dataMapKey] = ctx
|
||||||
|
@ -11,5 +11,6 @@ Markdown:
|
|||||||
ChromaStyle: monokai
|
ChromaStyle: monokai
|
||||||
|
|
||||||
Data:
|
Data:
|
||||||
|
debug: True
|
||||||
matomoSiteId: 89
|
matomoSiteId: 89
|
||||||
token: 89ff216524093123bf7a0a10f7b273 # cockpit api token
|
token: 89ff216524093123bf7a0a10f7b273 # cockpit api token
|
@ -100,15 +100,34 @@
|
|||||||
<!-- ========== Main Content ========== -->
|
<!-- ========== Main Content ========== -->
|
||||||
<div class="maincontent">
|
<div class="maincontent">
|
||||||
{% if Data.background %}
|
{% if Data.background %}
|
||||||
<img src="{{ Data.background|relative_path }}" alt="{{ Meta.Title }}" class="img2bg">
|
<img
|
||||||
|
src="{{ Data.background|image_process:"p=fill,w=1440,h=810,q=30" }}"
|
||||||
|
srcset="{{ Data.background|image_process:"p=fill,w=768,h=768,q=30" }} 768w,
|
||||||
|
{{ Data.background|image_process:"p=fill,w=1440,h=810,q=30" }} 1440w,
|
||||||
|
{{ Data.background|image_process:"p=fill,w=1920,h=1020,q=30" }} 1920w"
|
||||||
|
alt="{{ Meta.Title }}" class="img2bg">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="white_section section_padding">
|
<div class="white_section section_padding">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
{% block part1 %}
|
{% block part1 %}
|
||||||
{{ BodyParts.1 }}
|
{{ BodyParts.1 }}
|
||||||
{% endblock part1 %}
|
{% endblock part1 %}
|
||||||
{% if This.Data.img %}
|
|
||||||
|
{% if Data.debug %}
|
||||||
|
<hr>
|
||||||
|
<h2>DEBUG</h2>
|
||||||
|
|
||||||
|
<h3>This</h3>
|
||||||
|
<pre>{{ This|json:"pretty" }}</pre>
|
||||||
|
|
||||||
|
<h3>Data</h3>
|
||||||
|
<pre>{{ Data|json:"pretty" }}</pre>
|
||||||
|
|
||||||
|
<h3>NavMap</h3>
|
||||||
|
<pre>{{ NavMap|json: "pretty" }}</pre>
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user