diff --git a/build/RELEASE.md b/build/RELEASE.md index 689de60..d5783ae 100644 --- a/build/RELEASE.md +++ b/build/RELEASE.md @@ -2,6 +2,7 @@ NEUERUNGEN: - Cached Collection Webrequests - recursive Collections +- Datei basierte Collections - markdown-Filter `s=SYNTAX_HIGHLIGHT_SHEMA` Parameter - image_process nutzt alle CPU-Kerne - GZIP/Brotli Vor-Komprimierung der Inhalte und Assets diff --git a/pkg/filter/image_process.go b/pkg/filter/image_process.go index c564c79..f7ebf5a 100644 --- a/pkg/filter/image_process.go +++ b/pkg/filter/image_process.go @@ -130,7 +130,7 @@ func ImageProcessFilter(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, * } } else { // local file - imgSource = mark2web.ResolveInputPath(imgSource) + imgSource = mark2web.CurrentTreeNode.ResolveInputPath(imgSource) if p.Filename == "" { p.Filename = fmt.Sprintf( "%s_%s", @@ -142,7 +142,7 @@ func ImageProcessFilter(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, * var imgTarget string if p.TargetDir != "" { - imgTarget = mark2web.ResolveOutputPath( + imgTarget = mark2web.CurrentTreeNode.ResolveOutputPath( path.Clean(p.TargetDir) + "/" + p.Filename, ) @@ -158,10 +158,10 @@ func ImageProcessFilter(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, * } } - p.Filename = mark2web.ResolveNavPath(p.TargetDir + "/" + p.Filename) + p.Filename = mark2web.CurrentTreeNode.ResolveNavPath(p.TargetDir + "/" + p.Filename) } else { - imgTarget = mark2web.ResolveOutputPath(p.Filename) + imgTarget = mark2web.CurrentTreeNode.ResolveOutputPath(p.Filename) } if f, err := os.Stat(imgTarget); err == nil && !f.IsDir() { @@ -226,5 +226,5 @@ func ImageProcessFilter(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, * helper.Log.Noticef("finished image: %s", imgTarget) }) } - return pongo2.AsValue(mark2web.ResolveNavPath(p.Filename)), nil + return pongo2.AsValue(mark2web.CurrentTreeNode.ResolveNavPath(p.Filename)), nil } diff --git a/pkg/filter/image_process_test.go b/pkg/filter/image_process_test.go index 776e918..1608a25 100644 --- a/pkg/filter/image_process_test.go +++ b/pkg/filter/image_process_test.go @@ -36,9 +36,6 @@ func TestImageProcessFilter(t *testing.T) { }, }, } - mark2web.CurrentContext = &pongo2.Context{ - "CurrentPath": "", - } os.Remove("../../test/out/fit_300x300_q060_test.jpg") diff --git a/pkg/filter/relative_path.go b/pkg/filter/relative_path.go index 298909c..1a85bda 100644 --- a/pkg/filter/relative_path.go +++ b/pkg/filter/relative_path.go @@ -8,7 +8,7 @@ import ( // RelativePathFilter returns the relative path to navpoint based on current nav func RelativePathFilter(in, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { return pongo2.AsValue( - mark2web.ResolveNavPath( + mark2web.CurrentTreeNode.ResolveNavPath( in.String(), ), ), nil diff --git a/pkg/filter/relative_path_test.go b/pkg/filter/relative_path_test.go index 71ed2e4..c61cd4e 100644 --- a/pkg/filter/relative_path_test.go +++ b/pkg/filter/relative_path_test.go @@ -17,10 +17,23 @@ func TestRelativePathFilter(t *testing.T) { "testabs": "/abs", "testsub": "../sub/rel", } + + mark2web.Config.Directories.Output = "../../test/out" + + mark2web.CurrentTreeNode = &mark2web.TreeNode{ + InputPath: "../../test/in/content", + OutputPath: "../../test/out/sub", + Config: &mark2web.PathConfig{ + Imaging: &mark2web.ImagingConfig{ + Quality: 60, + Height: 300, + Width: 300, + Process: "fit", + }, + }, + } + Convey("parse template", func() { - mark2web.CurrentContext = &pongo2.Context{ - "CurrentPath": "sub", - } output, err := pongo2.RenderTemplateString("{{ testrel|relative_path }}", ctx) So(err, ShouldBeNil) diff --git a/pkg/helper/dir.go b/pkg/helper/dir.go index e677d78..3694cdc 100644 --- a/pkg/helper/dir.go +++ b/pkg/helper/dir.go @@ -2,7 +2,6 @@ package helper import ( "os" - "strings" ) // CreateDirectory creates direcory with all missing parents and panic if error @@ -25,14 +24,3 @@ func CreateDirectory(dir string) { Log.Panicf("unknown error for output directory '%s': %s", dir, err) } } - -// BackToRoot builds ../../ string -func BackToRoot(curNavPath string) string { - tmpPath := "" - if curNavPath != "" { - for i := strings.Count(curNavPath, "/") + 1; i > 0; i-- { - tmpPath += "../" - } - } - return tmpPath -} diff --git a/pkg/helper/regexp.go b/pkg/helper/regexp.go new file mode 100644 index 0000000..cfc2f77 --- /dev/null +++ b/pkg/helper/regexp.go @@ -0,0 +1,18 @@ +package helper + +import "regexp" + +// GetRegexpParams gets a map of named regexp group matches +// use pe. (?P\d{4})-(?P\d{2})-(?P\d{2}) as regexp +func GetRegexpParams(regEx *regexp.Regexp, str string) (paramsMap map[string]string) { + + match := regEx.FindStringSubmatch(str) + + paramsMap = make(map[string]string) + for i, name := range regEx.SubexpNames() { + if i > 0 && i <= len(match) { + paramsMap[name] = match[i] + } + } + return +} diff --git a/pkg/mark2web/assets.go b/pkg/mark2web/assets.go index 51c5012..2c6bdbf 100644 --- a/pkg/mark2web/assets.go +++ b/pkg/mark2web/assets.go @@ -35,13 +35,13 @@ func ProcessAssets() { } // fixAssetsPath replaces assets path based on current path -func fixAssetsPath(str, curNavPath string) string { +func (node *TreeNode) fixAssetsPath(str string) string { if find := Config.Assets.FixTemplate.Find; find != "" { - helper.Log.Debugf("fixing assets paths for path '%s'", curNavPath) + helper.Log.Debugf("fixing assets paths for path '%s'", node.CurrentNavPath()) repl := Config.Assets.FixTemplate.Replace toPath := Config.Assets.ToPath - bToRoot := helper.BackToRoot(curNavPath) + bToRoot := node.BackToRootPath() regex, err := regexp.Compile(find) if err != nil { log.Panicf("could not compile regexp '%s' for assets path: %s", find, err) diff --git a/pkg/mark2web/collection.go b/pkg/mark2web/collection.go index 2d34b5b..e6f3d76 100644 --- a/pkg/mark2web/collection.go +++ b/pkg/mark2web/collection.go @@ -1,7 +1,9 @@ package mark2web import ( + "io/ioutil" "path" + "regexp" "strings" "gitbase.de/apairon/mark2web/pkg/helper" @@ -20,13 +22,12 @@ var colCache = make(map[string]*colCacheEntry) func (node *TreeNode) handleCollections() { collections := append(node.Config.Collections, node.Config.This.Collections...) for _, colConfig := range collections { - if colConfig != nil { - if colConfig.Name == nil || *colConfig.Name == "" { - helper.Log.Panicf("missing Name in collection config in '%s'", node.InputPath) - } - if colConfig.URL == nil || *colConfig.URL == "" { - helper.Log.Panicf("missing EntriesJSON in collection config in '%s'", node.InputPath) - } + if colConfig.Name == nil || *colConfig.Name == "" { + helper.Log.Panicf("missing Name in collection config in '%s'", node.InputPath) + } + if (colConfig.URL == nil || *colConfig.URL == "") && + (colConfig.Directory == nil) { + helper.Log.Panicf("missing URL and Directory in collection config in '%s'", node.InputPath) } if node.ColMap == nil { @@ -36,21 +37,73 @@ func (node *TreeNode) handleCollections() { ctx["This"] = node.Config.This ctx["Data"] = node.Config.Data - url, err := pongo2.RenderTemplateString(*colConfig.URL, ctx) - if err != nil { - helper.Log.Panicf("invalid template string for Collection Element.URL in '%s': %s", node.InputPath, err) - } - var colData interface{} - if cacheEntry, ok := colCache[url]; ok { - colData = cacheEntry.data - cacheEntry.hit++ - } else { - colData = helper.JSONWebRequest(url) - colCache[url] = &colCacheEntry{ - data: colData, - navnames: make([]string, 0), + + errSrcText := "" + cacheKey := "" + + if colConfig.URL != nil { + url, err := pongo2.RenderTemplateString(*colConfig.URL, ctx) + if err != nil { + helper.Log.Panicf("invalid template string for Collection Element.URL in '%s': %s", node.InputPath, err) } + + errSrcText = "URL " + url + cacheKey = url + + if cacheEntry, ok := colCache[url]; ok { + colData = cacheEntry.data + cacheEntry.hit++ + } else { + helper.Log.Noticef("reading collection from: %s", errSrcText) + colData = helper.JSONWebRequest(url) + colCache[url] = &colCacheEntry{ + data: colData, + navnames: make([]string, 0), + } + } + + } else { + path := node.ResolveInputPath(colConfig.Directory.Path) + errSrcText = "DIR " + path + + helper.Log.Noticef("reading collection from: %s", errSrcText) + d, err := ioutil.ReadDir(path) + if err != nil { + helper.Log.Panicf("could not read directory '%s': %s", path, err) + } + + mStr := "." + if colConfig.Directory.MatchFilename != "" { + mStr = colConfig.Directory.MatchFilename + } + matcher, err := regexp.Compile(mStr) + if err != nil { + helper.Log.Panicf("could not compile regex for MatchFilename '%s' in '%s': %s", mStr, path, err) + } + + if colConfig.Directory.ReverseOrder { + for i := len(d)/2 - 1; i >= 0; i-- { + opp := len(d) - 1 - i + d[i], d[opp] = d[opp], d[i] + } + } + + fcolData := make([]pongo2.Context, 0) + for _, fh := range d { + if !fh.IsDir() && matcher.MatchString(fh.Name()) { + inFile := path + "/" + fh.Name() + md, err := ioutil.ReadFile(inFile) + if err != nil { + helper.Log.Panicf("could not read file '%s': %s", inFile, err) + } + _, ctx := node.processMarkdownWithHeader(md, inFile) + (*ctx)["FilenameMatch"] = helper.GetRegexpParams(matcher, fh.Name()) + fcolData = append(fcolData, *ctx) + } + } + + colData = fcolData } node.ColMap[*colConfig.Name] = colData @@ -64,7 +117,7 @@ func (node *TreeNode) handleCollections() { entries, ok = colDataMap[navT.EntriesAttribute].([]interface{}) if !ok { helper.Log.Debug(spew.Sdump(colDataMap)) - helper.Log.Panicf("invalid json data in [%s] from url '%s' for entries", navT.EntriesAttribute, url) + helper.Log.Panicf("invalid json data in [%s] from '%s' for entries", navT.EntriesAttribute, errSrcText) } } } else { @@ -72,7 +125,7 @@ func (node *TreeNode) handleCollections() { } if !ok { helper.Log.Debug(spew.Sdump(colData)) - helper.Log.Panicf("invalid json data from url '%s', need array of objects for entries or object with configured NavTemplate.EntriesAttribute", url) + helper.Log.Panicf("invalid json data from '%s', need array of objects for entries or object with configured NavTemplate.EntriesAttribute", errSrcText) } // build navigation with detail sites @@ -85,7 +138,7 @@ func (node *TreeNode) handleCollections() { var jsonCtx map[string]interface{} if jsonCtx, ok = colEl.(map[string]interface{}); !ok { helper.Log.Debug(spew.Sdump(colEl)) - helper.Log.Panicf("no json object for entry index %d from url '%s'", idx, url) + helper.Log.Panicf("no json object for entry index %d from '%s'", idx, errSrcText) } err = helper.Merge(&ctxE, pongo2.Context(jsonCtx)) if err != nil { @@ -143,14 +196,14 @@ func (node *TreeNode) handleCollections() { } } - if l := len(colCache[url].navnames); colCache[url].hit > 1 && + if l := len(colCache[cacheKey].navnames); colCache[cacheKey].hit > 1 && l > 0 && - navname == colCache[url].navnames[l-1] { + navname == colCache[cacheKey].navnames[l-1] { // navname before used same url, so recursion loop - helper.Log.Panicf("collection request loop detected for in '%s' for url: %s", node.InputPath, url) + helper.Log.Panicf("collection request loop detected for in '%s' for : %s", node.InputPath, errSrcText) } - colCache[url].navnames = append(colCache[url].navnames, navname) + colCache[cacheKey].navnames = append(colCache[cacheKey].navnames, navname) node.addSubNode(tpl, goTo, navname, colEl, dataKey, body, navT.Hidden) } diff --git a/pkg/mark2web/config_path.go b/pkg/mark2web/config_path.go index 8da2020..8531a23 100644 --- a/pkg/mark2web/config_path.go +++ b/pkg/mark2web/config_path.go @@ -2,10 +2,18 @@ package mark2web import "gitbase.de/apairon/mark2web/pkg/helper" +// CollectionDirectoryConfig specifies how to handle a directory of markdown files as a collection +type CollectionDirectoryConfig struct { + Path string `yaml:"Path"` + MatchFilename string `yaml:"MatchFilename"` + ReverseOrder bool `yaml:"ReverseOrder"` +} + // CollectionConfig describes a collection type CollectionConfig struct { - Name *string `yaml:"Name"` - URL *string `yaml:"URL"` + Name *string `yaml:"Name"` + URL *string `yaml:"URL"` + Directory *CollectionDirectoryConfig `yaml:"Directory"` NavTemplate *struct { EntriesAttribute string `yaml:"EntriesAttribute"` GoTo string `yaml:"GoTo"` diff --git a/pkg/mark2web/content.go b/pkg/mark2web/content.go index 01f5bce..014fa06 100644 --- a/pkg/mark2web/content.go +++ b/pkg/mark2web/content.go @@ -65,24 +65,104 @@ func (node *TreeNode) ReadContentDir(inBase string, outBase string, dir string, } } +func (node *TreeNode) processMarkdownWithHeader(md []byte, errorRef string) (*PathConfig, *pongo2.Context) { + + newConfig := new(PathConfig) + + headerRegex := regexp.MustCompile("(?s)^---(.*?)\\r?\\n\\r?---\\r?\\n\\r?") + yamlData := headerRegex.Find(md) + if string(yamlData) != "" { + // replace tabs + yamlData = bytes.Replace(yamlData, []byte("\t"), []byte(" "), -1) + + helper.Log.Debugf("found yaml header in '%s', merging config", errorRef) + err := yaml.Unmarshal(yamlData, newConfig) + if err != nil { + helper.Log.Panicf("could not parse YAML header from '%s': %s", errorRef, err) + } + + helper.Log.Debug("merging config with upper config") + oldThis := newConfig.This + helper.Merge(newConfig, node.Config) + newConfig.This = oldThis + + helper.Log.Debug(spew.Sdump(newConfig)) + + md = headerRegex.ReplaceAll(md, []byte("")) + } else { + helper.Merge(newConfig, node.Config) + } + + // use --- for splitting document in markdown parts + regex := regexp.MustCompile("\\r?\\n\\r?---\\r?\\n\\r?") + inputParts := regex.Split(string(md), -1) + htmlParts := make([]*pongo2.Value, 0) + + chromaRenderer := false + chromaStyle := "monokai" + if m := newConfig.Markdown; m != nil { + if m.ChromaRenderer != nil && *m.ChromaRenderer { + chromaRenderer = true + } + if m.ChromaStyle != nil && *m.ChromaStyle != "" { + chromaStyle = *m.ChromaStyle + } + } + for _, iPart := range inputParts { + htmlParts = append(htmlParts, + pongo2.AsSafeValue( + string(helper.RenderMarkdown([]byte(iPart), chromaRenderer, chromaStyle)))) + } + + // build navigation + navMap := make(map[string]*NavElement) + navSlice := make([]*NavElement, 0) + navActive := make([]*NavElement, 0) + node.buildNavigation(&navMap, &navSlice, &navActive) + + // read yaml header as data for template + ctx := NewContext() + ctx["This"] = newConfig.This + ctx["Meta"] = newConfig.Meta + ctx["Markdown"] = newConfig.Markdown + ctx["Data"] = newConfig.Data + ctx["ColMap"] = node.root.ColMap // root as NavMap and NavSlice, for sub go to NavElement.ColMap + ctx["NavMap"] = navMap + ctx["NavSlice"] = navSlice + ctx["NavActive"] = navActive + ctx["Body"] = pongo2.AsSafeValue(string(helper.RenderMarkdown(md, chromaRenderer, chromaStyle))) + ctx["BodyParts"] = htmlParts + ctx["CurrentPath"] = node.CurrentNavPath() + // set active nav element + if len(navActive) > 0 { + ctx["NavElement"] = navActive[len(navActive)-1] + } else { + // if no active path to content, we are in root dir + ctx["NavElement"] = &NavElement{ + GoTo: node.BackToRootPath(), + Active: true, + ColMap: node.ColMap, + Data: node.Config.Data, + This: node.Config.This, + SubMap: &navMap, + SubSlice: &navSlice, + } + } + + return newConfig, &ctx +} + // ProcessContent walks recursivly through the input paths and processes all files for output func (node *TreeNode) ProcessContent() { helper.CreateDirectory(node.OutputPath) - curNavPath := strings.TrimPrefix(node.OutputPath, Config.Directories.Output) - curNavPath = strings.TrimPrefix(curNavPath, "/") - curNavPath = path.Clean(curNavPath) - if curNavPath == "." { - curNavPath = "" - } - if node.root != node { // write htaccess for rewrites, root will be written in WriteWebserverConfig() goTo := node.Config.This.GoTo if goTo != nil && *goTo != "" { goToFixed := *goTo if strings.HasPrefix(goToFixed, "/") { - goToFixed = helper.BackToRoot(curNavPath) + goToFixed + goToFixed = node.BackToRootPath() + goToFixed } goToFixed = path.Clean(goToFixed) @@ -91,82 +171,63 @@ func (node *TreeNode) ProcessContent() { } for _, file := range node.InputFiles { - var input []byte inFile := "InputString" - if file != "" { - inFile = node.InputPath + "/" + file - helper.Log.Debugf("reading file: %s", inFile) - - var err error - input, err = ioutil.ReadFile(inFile) - if err != nil { - helper.Log.Panicf("could not read '%s':%s", inFile, err) - } - helper.Log.Infof("processing input file '%s'", inFile) - } else { - // use input string if available and input filename == "" - var inputString *string - if i := node.Config.Index; i != nil { - inputString = i.InputString - } - if inputString != nil { - helper.Log.Debugf("using input string instead of file") - input = []byte(*inputString) - } - } - - newConfig := new(PathConfig) - - regex := regexp.MustCompile("(?s)^---(.*?)\\r?\\n\\r?---\\r?\\n\\r?") - yamlData := regex.Find(input) - if string(yamlData) != "" { - // replace tabs - yamlData = bytes.Replace(yamlData, []byte("\t"), []byte(" "), -1) - - helper.Log.Debugf("found yaml header in '%s', merging config", inFile) - err := yaml.Unmarshal(yamlData, newConfig) - if err != nil { - helper.Log.Panicf("could not parse YAML header from '%s': %s", inFile, err) - } - - helper.Log.Debug("merging config with upper config") - oldThis := newConfig.This - helper.Merge(newConfig, node.Config) - newConfig.This = oldThis - - helper.Log.Debug(spew.Sdump(newConfig)) - - input = regex.ReplaceAll(input, []byte("")) - } else { - helper.Merge(newConfig, node.Config) - } - // ignore ??? ignoreFile := false - var ignoreRegex *string - var stripRegex *string - var outputExt *string - if f := newConfig.Filename; f != nil { - ignoreRegex = f.Ignore - stripRegex = f.Strip - outputExt = f.OutputExtension - } - if ignoreRegex != nil && *ignoreRegex != "" { - regex, err := regexp.Compile(*ignoreRegex) - if err != nil { - helper.Log.Panicf("could not compile filename.ignore regexp '%s' for file '%s': %s", *ignoreRegex, inFile, err) + if file != "" { + inFile = node.InputPath + "/" + file + var ignoreRegex *string + if f := node.Config.Filename; f != nil { + ignoreRegex = f.Ignore + } + if ignoreRegex != nil && *ignoreRegex != "" { + regex, err := regexp.Compile(*ignoreRegex) + if err != nil { + helper.Log.Panicf("could not compile filename.ignore regexp '%s' for file '%s': %s", *ignoreRegex, inFile, err) + } + ignoreFile = regex.MatchString(file) } - ignoreFile = regex.MatchString(file) } if ignoreFile { helper.Log.Infof("ignoring file '%s', because of filename.ignore", inFile) } else { + var input []byte + + if file != "" { + helper.Log.Debugf("reading file: %s", inFile) + + var err error + input, err = ioutil.ReadFile(inFile) + if err != nil { + helper.Log.Panicf("could not read '%s':%s", inFile, err) + } + helper.Log.Infof("processing input file '%s'", inFile) + } else { + // use input string if available and input filename == "" + var inputString *string + if i := node.Config.Index; i != nil { + inputString = i.InputString + } + if inputString != nil { + helper.Log.Debugf("using input string instead of file") + input = []byte(*inputString) + } + } + + newConfig, ctx := node.processMarkdownWithHeader(input, inFile) // build output filename outputFilename := file + var stripRegex *string + var outputExt *string + if f := newConfig.Filename; f != nil { + stripRegex = f.Strip + outputExt = f.OutputExtension + } + var indexInputFile *string var indexOutputFile *string if i := newConfig.Index; i != nil { @@ -194,71 +255,14 @@ func (node *TreeNode) ProcessContent() { outFile := node.OutputPath + "/" + outputFilename helper.Log.Debugf("using '%s' as output file", outFile) - - // use --- for splitting document in markdown parts - regex := regexp.MustCompile("\\r?\\n\\r?---\\r?\\n\\r?") - inputParts := regex.Split(string(input), -1) - htmlParts := make([]*pongo2.Value, 0) - - chromaRenderer := false - chromaStyle := "monokai" - if m := newConfig.Markdown; m != nil { - if m.ChromaRenderer != nil && *m.ChromaRenderer { - chromaRenderer = true - } - if m.ChromaStyle != nil && *m.ChromaStyle != "" { - chromaStyle = *m.ChromaStyle - } - } - for _, iPart := range inputParts { - htmlParts = append(htmlParts, - pongo2.AsSafeValue( - string(helper.RenderMarkdown([]byte(iPart), chromaRenderer, chromaStyle)))) - } - - // build navigation - navMap := make(map[string]*NavElement) - navSlice := make([]*NavElement, 0) - navActive := make([]*NavElement, 0) - buildNavigation(node.root, &navMap, &navSlice, &navActive, curNavPath) - - // read yaml header as data for template - ctx := NewContext() - ctx["This"] = newConfig.This - ctx["Meta"] = newConfig.Meta - ctx["Markdown"] = newConfig.Markdown - ctx["Data"] = newConfig.Data - ctx["ColMap"] = node.root.ColMap // root as NavMap and NavSlice, for sub go to NavElement.ColMap - ctx["NavMap"] = navMap - ctx["NavSlice"] = navSlice - ctx["NavActive"] = navActive - ctx["Body"] = pongo2.AsSafeValue(string(helper.RenderMarkdown(input, chromaRenderer, chromaStyle))) - ctx["BodyParts"] = htmlParts - ctx["CurrentPath"] = curNavPath - // set active nav element - if len(navActive) > 0 { - ctx["NavElement"] = navActive[len(navActive)-1] - } else { - // if no active path to content, we are in root dir - ctx["NavElement"] = &NavElement{ - GoTo: helper.BackToRoot(curNavPath), - Active: true, - ColMap: node.ColMap, - Data: node.Config.Data, - This: node.Config.This, - SubMap: &navMap, - SubSlice: &navSlice, - } - } - helper.Log.Debugf("rendering template '%s' for '%s'", *newConfig.Template, outFile) templateFilename := *newConfig.Template - result, err := renderTemplate(*newConfig.Template, node, newConfig, &ctx) + result, err := renderTemplate(*newConfig.Template, node, newConfig, ctx) if err != nil { helper.Log.Panicf("could not execute template '%s' for input file '%s': %s", templateFilename, inFile, err) } - result = fixAssetsPath(result, curNavPath) + result = node.fixAssetsPath(result) helper.Log.Noticef("writing to output file: %s", outFile) err = ioutil.WriteFile(outFile, []byte(result), 0644) diff --git a/pkg/mark2web/navigation.go b/pkg/mark2web/navigation.go index 23326a1..9a1b737 100644 --- a/pkg/mark2web/navigation.go +++ b/pkg/mark2web/navigation.go @@ -25,7 +25,11 @@ type NavElement struct { } // buildNavigation builds the navigation trees for use in templates -func buildNavigation(tree *TreeNode, curNavMap *map[string]*NavElement, curNavSlice *[]*NavElement, navActive *[]*NavElement, activeNav string) { +func (node *TreeNode) buildNavigation(curNavMap *map[string]*NavElement, curNavSlice *[]*NavElement, navActive *[]*NavElement) { + buildNavigationRecursive(node.root, curNavMap, curNavSlice, navActive, node.CurrentNavPath(), node.BackToRootPath()) +} + +func buildNavigationRecursive(tree *TreeNode, curNavMap *map[string]*NavElement, curNavSlice *[]*NavElement, navActive *[]*NavElement, activeNav string, backToRoot string) { for _, el := range tree.Sub { if el.Hidden { continue // ignore hidden nav points from collections @@ -88,8 +92,7 @@ func buildNavigation(tree *TreeNode, curNavMap *map[string]*NavElement, curNavSl if activeNav != "" && activeNav != "/" { // calculate relative path - bToRoot := helper.BackToRoot(activeNav) - navEl.GoTo = bToRoot + navEl.GoTo + navEl.GoTo = backToRoot + navEl.GoTo navEl.GoTo = path.Clean(navEl.GoTo) } @@ -98,6 +101,6 @@ func buildNavigation(tree *TreeNode, curNavMap *map[string]*NavElement, curNavSl *curNavSlice = append(*curNavSlice, &navEl) } - buildNavigation(el, &subMap, &subSlice, navActive, activeNav) + buildNavigationRecursive(el, &subMap, &subSlice, navActive, activeNav, backToRoot) } } diff --git a/pkg/mark2web/path.go b/pkg/mark2web/path.go index 5aa3f15..3b53716 100644 --- a/pkg/mark2web/path.go +++ b/pkg/mark2web/path.go @@ -3,36 +3,58 @@ package mark2web import ( "path" "strings" - - "gitbase.de/apairon/mark2web/pkg/helper" ) // ResolveNavPath fixes nav target relative to current navigation path -func ResolveNavPath(target string) string { - curNavPath := (*CurrentContext)["CurrentPath"].(string) +func (node *TreeNode) ResolveNavPath(target string) string { if strings.HasPrefix(target, "/") { - target = helper.BackToRoot(curNavPath) + target + target = node.BackToRootPath() + target } target = path.Clean(target) return target } // ResolveOutputPath fixes output directory relative to current navigation path -func ResolveOutputPath(target string) string { +func (node *TreeNode) ResolveOutputPath(target string) string { if strings.HasPrefix(target, "/") { target = Config.Directories.Output + "/" + target } else { - target = CurrentTreeNode.OutputPath + "/" + target + target = node.OutputPath + "/" + target } return path.Clean(target) } // ResolveInputPath fixes input directory relative to current navigation path -func ResolveInputPath(target string) string { +func (node *TreeNode) ResolveInputPath(target string) string { if strings.HasPrefix(target, "/") { target = Config.Directories.Input + "/" + target } else { - target = CurrentTreeNode.InputPath + "/" + target + target = node.InputPath + "/" + target } return path.Clean(target) } + +// CurrentNavPath is current navigation path for this node +func (node *TreeNode) CurrentNavPath() string { + curNavPath := strings.TrimPrefix(node.OutputPath, Config.Directories.Output) + curNavPath = strings.TrimPrefix(curNavPath, "/") + curNavPath = path.Clean(curNavPath) + if curNavPath == "." { + curNavPath = "" + } + + return curNavPath +} + +// BackToRootPath builds ../../ string +func (node *TreeNode) BackToRootPath() string { + curNavPath := node.CurrentNavPath() + + tmpPath := "" + if curNavPath != "" { + for i := strings.Count(curNavPath, "/") + 1; i > 0; i-- { + tmpPath += "../" + } + } + return tmpPath +} diff --git a/website/content/de/01_Navigation/02_Installation/README.md b/website/content/de/01_Navigation/02_Installation/README.md index 3b0fc05..c355731 100644 --- a/website/content/de/01_Navigation/02_Installation/README.md +++ b/website/content/de/01_Navigation/02_Installation/README.md @@ -10,23 +10,16 @@ Data: --- # Installation -Damit die korrekten Versionsinformationen dynamisch in das finale mark2web-Binary eingefügt wurde, ist eine manuelle Installation aus dem Git-Repository sinnvoll. -Da die benötigten Pakete über die Go "vendor"-Funktionalität eingebunden sind ist ein `git submodule --init --recursive` nötig, wie im folgenden Abschnitt zu sehen ist: - ```sh -mkdir -p $GOPATH/src/gitbase.de/apairon -git clone https://gitbase.de/apairon/mark2web.git $GOPATH/src/gitbase.de/apairon/mark2web +go get -v gitbase.de/apairon/mark2web/cmd/mark2web -cd $GOPATH/src/gitbase.de/apairon/mark2web -git submodule update --init --recursive - -./build.sh +# setze Versioninformationen ins Binary +pkg=$GOPATH/src/gitbase.de/apairon/mark2web +go install -v -ldflags "-X main.Version=`cat $pkg/build/VERSION` -X main.GitHash=`git --git-dir $pkg/.git rev-parse HEAD` -X main.BuildTime=`date -u '+%Y-%m-%d_%I:%M:%S%p'`" gitbase.de/apairon/mark2web/cmd/mark2web ``` --- -Eine Installation über `go install gitbase.de/apairon/mark2web` wird derzeit noch nicht unterstützt, da dabei die Informationen für `mark2web -version` nicht generiert werden. - ## Releases Vorkompilierte Binaries finden Sie auf der [Releases-Seite auf gitbase.de](https://gitbase.de/apairon/mark2web/releases). \ No newline at end of file diff --git a/website/content/de/01_Navigation/02_Installation/bild.jpg b/website/content/de/01_Navigation/02_Installation/bild.jpg deleted file mode 100644 index 627f349..0000000 Binary files a/website/content/de/01_Navigation/02_Installation/bild.jpg and /dev/null differ diff --git a/website/content/de/01_Navigation/03_Benutzung/02_Konfiguration/README.md b/website/content/de/01_Navigation/03_Benutzung/02_Konfiguration/README.md deleted file mode 100644 index f243e05..0000000 --- a/website/content/de/01_Navigation/03_Benutzung/02_Konfiguration/README.md +++ /dev/null @@ -1,150 +0,0 @@ ---- -Data: - background: /img/wire.jpg - - slider: - - img: /img/wire.jpg - alt: - opacity: 1 - ---- - -# Konfiguration - -Die Konfigurationsdatein sind im YAML-Format gehalten (siehe: [Wikipedia](https://de.wikipedia.org/wiki/YAML)). - -## globale Einstellungen - -Die obersten Verzeichnis sich befindende Datei `config.yml` kann z.B. folgenden Inhalt haben: - -```yaml -Webserver: - Type: "apache" - -Assets: - FromPath: "assets" - ToPath: "assets" - Action: "copy" - FixTemplate: - Find: "\\.\\./assets/" - Replace: "" - -OtherFiles: - Action: "copy" -``` - -### Sektion `Webserver:` - -#### `Type:` - -Derzeit wird hier nur der Wert `apache` unterstützt. Ist dieser Wert gesetzt werden automatische .htaccess-Dateien mit mod_rewrite-Anweisungen generiert, die eine saubere Weiterleitung bei entsprechenden Konfig-Anweisungen im `content`-Verzeichnis ermöglichen. - -### Sektion `Assets:` - -`Assets:` steuert, wie mit Bild/JS/CSS Dateien umgegangen werden soll. - -#### `FromPath:` - -Lage des Asset-Verzeichnis unterhalb des `content`-Verzeichnis - -#### `ToPath:` - -Zielverzeichnis im Ausgabe-Verzeichnis der fertig generierten Website - -#### `Action:` - -Derzeit nur `copy`, also das Kopieren der Dateien und Unterordner ins Zielverzeichnis - -#### `FixTemplate:` - -Wenn hier `Find:` (regulärer Ausdruck) und `Replace:` (Ersetzung) angeben sind, werden die gefundenden Pfadangaben in der generierten HTML-Dateien durch den korrekten relativen Pfad zum Asset-Verzeichnis ersetzt. - -### Sektion `OtherFiles:` - -`OtherFiles:` definiert, wie mit anderen Dateien innerhalb des `content`-Verzeichnis umgegangen werden soll. - -#### `Action:` - -Derzeit nur `copy`, also das Kopieren der Dateien in das entsprechende Unterverzeichnis im Ausgabe-Verzeichnis - ---- - -## Konfiguration im `content`-Verzeichnis - -Im `content`-Verzeichnis, sowie in jedem Unterverzeichnis unterhalb von `content` kann sich eine `config.yml`-Datei befinden, wie aus folgendem Beispiel: - -```yaml -This: - GoTo: "/de/service/impressum/" - Navname: "Impressumsverweis" - -``` - -oder - -```yaml -This: - Navname: "FAQ's" - Data: - slogan: "Wer nicht fragt, bekommt keine Antwort." - -Template: "base.html" - -Index: - InputFile: "README.md" - OutputFile: "index.html" - -Meta: - Title: "Fragen und Antworten" - Description: "Dies ist die Fragen und Antworten Unterseite." - Keywords: "FAQ, Fragen, Antworten" - -Data: - background: "bg.jpg" - slider: - - img: "assets/img/slider1.jpg" - alt: "Alternativtext 1" - - img: "assets/img/slider2.jpg" - alt: "Alternativtext 2" - - img: "assets/img/slider3.jpg" - alt: "Alternativtext 3" - -``` - -### `This:` Sektion - -Sämtlich Werte unterhalb dieser Sektion gelten nur für den Inhalt, bzw. Navigationspunkt in dessen Ordner sich die `config.yml` befindet. Die Werte werden nicht an Unterordner wertervererbt. - -#### `GoTo:` - -Falls der Navigationspunkt selbst keinen Inhalt darstellen soll, sondern nur weiterleiten soll, so wird hier das Weiterleitungsziel eingegeben. -Das Ziel ist der absolute (startend mit `/`) oder relative Pfad zum Zielnavigationspunkt. -Die Schreibweise des Pfades ist so zu verwenden, wie der Pfad nach Umschreibung und Säuberung des Pfades im Zielverzeichnis dargestellt wird. -Aus `de/mainnav/03_Fragen und Antworten` wird also z.B. `de/mainnav/fragen-und-antworten`. - -#### `Navname:` - -Dieser Wert überschreibt den aus dem Ordnernamen automatisch abgeleiteten Navigationspunkt-Namen. Dies ist zum Beispiel dann nützlich, wenn Sonderzeichen im Verzeichnisnamen nicht vorkommen sollen, aber im Namen des Navigationspunkts gebraucht werden. - -#### `Data:` - -Unterhalb von `Data:` können beliebige Datenstrukturen erfasst werden. Da diese Struktur unterhalb von `This:` angeordnet ist, werden auch die Daten nicht weiter an Unterordner vererbt. -Hier können z.B. Informationen zum Navigationspunkt abgelegt werden, die im Template Zusatzinformationen darstellen (z.B. ein Slogan zu einem Navigationspunkt). - -### `Meta:` Sektion - -Unter `Title:`, `Description:` und `Keywords:` werden die typischen Metaangaben abgelegt, die im - -```html - - ... - -``` - -übllicherweise Verwendung finden. Die entsprechenden Platzhalter stehen im Template zur Verfügung. - -`Meta:` vererbt seine individuellen Informationen an die Unterordner weiter, sofern diese dort nicht selbst in einer `config.yml` oder im Kopf der Markdown-Datei definiert sind. - -### `Data:` Sektion - -`Data:` an dieser Stelle kann, wie auch `Data:` unterhalb von `This:`, beliebige Daten aufnehmen. Die Daten hier allerdings werden an Unterordner weitervererbt, sofern diese nicht dort oder in der Markdown-Datei selbst festegelegt überschrieben wurden. \ No newline at end of file diff --git a/website/content/de/01_Navigation/03_Benutzung/02_Konfiguration/config.yml b/website/content/de/01_Navigation/03_Benutzung/02_Konfiguration/config.yml deleted file mode 100644 index c7675ab..0000000 --- a/website/content/de/01_Navigation/03_Benutzung/02_Konfiguration/config.yml +++ /dev/null @@ -1,3 +0,0 @@ -This: - Data: - teaser: Globale Konfiguration und individuelle Content-Einstellungen \ No newline at end of file diff --git a/website/content/de/01_Navigation/03_Benutzung/01_Ordnerstruktur/README.md b/website/content/de/01_Navigation/03_Dokumentation/01_Ordnerstruktur/README.md similarity index 100% rename from website/content/de/01_Navigation/03_Benutzung/01_Ordnerstruktur/README.md rename to website/content/de/01_Navigation/03_Dokumentation/01_Ordnerstruktur/README.md diff --git a/website/content/de/01_Navigation/03_Benutzung/01_Ordnerstruktur/config.yml b/website/content/de/01_Navigation/03_Dokumentation/01_Ordnerstruktur/config.yml similarity index 100% rename from website/content/de/01_Navigation/03_Benutzung/01_Ordnerstruktur/config.yml rename to website/content/de/01_Navigation/03_Dokumentation/01_Ordnerstruktur/config.yml diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/README.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/README.md new file mode 100644 index 0000000..932cf6a --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/README.md @@ -0,0 +1,16 @@ +--- +Template: base_doc.html + +Data: + background: /img/wire.jpg + + slider: + - img: /img/wire.jpg + alt: + opacity: 1 + +--- + +# Konfiguration + +Die Konfigurationsdatein sind im YAML-Format gehalten (siehe: [Wikipedia](https://de.wikipedia.org/wiki/YAML)). diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01000_globale Einstellungen.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01000_globale Einstellungen.md new file mode 100644 index 0000000..70d15e7 --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01000_globale Einstellungen.md @@ -0,0 +1,17 @@ +Die obersten Verzeichnis sich befindende Datei `config.yml` kann z.B. folgenden Inhalt haben: + +```yaml +Webserver: + Type: "apache" + +Assets: + FromPath: "assets" + ToPath: "assets" + Action: "copy" + FixTemplate: + Find: "\\.\\./assets/" + Replace: "" + +OtherFiles: + Action: "copy" +``` diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01100__Sektion Webserver.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01100__Sektion Webserver.md new file mode 100644 index 0000000..d65ed69 --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01100__Sektion Webserver.md @@ -0,0 +1,5 @@ +--- +Data: + Version: "ab v1.0" + +--- diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01110___Type.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01110___Type.md new file mode 100644 index 0000000..1a86cb0 --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01110___Type.md @@ -0,0 +1,7 @@ +--- +Data: + Version: "ab v1.0" + +--- + +Derzeit wird hier nur der Wert `apache` unterstützt. Ist dieser Wert gesetzt werden automatische .htaccess-Dateien mit mod_rewrite-Anweisungen generiert, die eine saubere Weiterleitung bei entsprechenden Konfig-Anweisungen im `content`-Verzeichnis ermöglichen. diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01200__Sektion Assets.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01200__Sektion Assets.md new file mode 100644 index 0000000..0062257 --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01200__Sektion Assets.md @@ -0,0 +1,7 @@ +--- +Data: + Version: "ab v1.0" + +--- + +`Assets:` steuert, wie mit Bild/JS/CSS Dateien umgegangen werden soll. diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01210___FromPath.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01210___FromPath.md new file mode 100644 index 0000000..04dae3a --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01210___FromPath.md @@ -0,0 +1,7 @@ +--- +Data: + Version: "ab v1.0" + +--- + +Lage des Asset-Verzeichnis unterhalb des `content`-Verzeichnis diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01220___ToPath.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01220___ToPath.md new file mode 100644 index 0000000..fd46fc8 --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01220___ToPath.md @@ -0,0 +1,7 @@ +--- +Data: + Version: "ab v1.0" + +--- + +Zielverzeichnis im Ausgabe-Verzeichnis der fertig generierten Website diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01230___Action.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01230___Action.md new file mode 100644 index 0000000..315b06f --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01230___Action.md @@ -0,0 +1,7 @@ +--- +Data: + Version: "ab v1.0" + +--- + +Derzeit nur `copy`, also das Kopieren der Dateien und Unterordner ins Zielverzeichnis diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01240___FixTemplates.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01240___FixTemplates.md new file mode 100644 index 0000000..78c1adb --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01240___FixTemplates.md @@ -0,0 +1,7 @@ +--- +Data: + Version: "ab v1.0" + +--- + +Wenn hier `Find:` (regulärer Ausdruck) und `Replace:` (Ersetzung) angeben sind, werden die gefundenden Pfadangaben in der generierten HTML-Dateien durch den korrekten relativen Pfad zum Asset-Verzeichnis ersetzt. diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01300__Sektion OtherFiles.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01300__Sektion OtherFiles.md new file mode 100644 index 0000000..d640036 --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01300__Sektion OtherFiles.md @@ -0,0 +1,7 @@ +--- +Data: + Version: "ab v1.0" + +--- + +`OtherFiles:` definiert, wie mit anderen Dateien innerhalb des `content`-Verzeichnis umgegangen werden soll. diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01310___Action.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01310___Action.md new file mode 100644 index 0000000..50b0fc2 --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_01310___Action.md @@ -0,0 +1,7 @@ +--- +Data: + Version: "ab v1.0" + +--- + +Derzeit nur `copy`, also das Kopieren der Dateien in das entsprechende Unterverzeichnis im Ausgabe-Verzeichnis diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02000_Konfiguration im Content-Verzeichnis.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02000_Konfiguration im Content-Verzeichnis.md new file mode 100644 index 0000000..67e8932 --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02000_Konfiguration im Content-Verzeichnis.md @@ -0,0 +1,45 @@ +--- +Data: + Version: "ab v1.0" + +--- + +Im `content`-Verzeichnis, sowie in jedem Unterverzeichnis unterhalb von `content` kann sich eine `config.yml`-Datei befinden, wie aus folgendem Beispiel: + +```yaml +This: + GoTo: "/de/service/impressum/" + Navname: "Impressumsverweis" + +``` + +oder + +```yaml +This: + Navname: "FAQ's" + Data: + slogan: "Wer nicht fragt, bekommt keine Antwort." + +Template: "base.html" + +Index: + InputFile: "README.md" + OutputFile: "index.html" + +Meta: + Title: "Fragen und Antworten" + Description: "Dies ist die Fragen und Antworten Unterseite." + Keywords: "FAQ, Fragen, Antworten" + +Data: + background: "bg.jpg" + slider: + - img: "assets/img/slider1.jpg" + alt: "Alternativtext 1" + - img: "assets/img/slider2.jpg" + alt: "Alternativtext 2" + - img: "assets/img/slider3.jpg" + alt: "Alternativtext 3" + +``` diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02100__Sektion This.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02100__Sektion This.md new file mode 100644 index 0000000..87db180 --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02100__Sektion This.md @@ -0,0 +1,7 @@ +--- +Data: + Version: "ab v1.0" + +--- + +Sämtlich Werte unterhalb dieser Sektion gelten nur für den Inhalt, bzw. Navigationspunkt in dessen Ordner sich die `config.yml` befindet. Die Werte werden nicht an Unterordner wertervererbt. diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02110___GoTo.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02110___GoTo.md new file mode 100644 index 0000000..7da7fb6 --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02110___GoTo.md @@ -0,0 +1,10 @@ +--- +Data: + Version: "ab v1.0" + +--- + +Falls der Navigationspunkt selbst keinen Inhalt darstellen soll, sondern nur weiterleiten soll, so wird hier das Weiterleitungsziel eingegeben. +Das Ziel ist der absolute (startend mit `/`) oder relative Pfad zum Zielnavigationspunkt. +Die Schreibweise des Pfades ist so zu verwenden, wie der Pfad nach Umschreibung und Säuberung des Pfades im Zielverzeichnis dargestellt wird. +Aus `de/mainnav/03_Fragen und Antworten` wird also z.B. `de/mainnav/fragen-und-antworten`. diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02120___Navname.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02120___Navname.md new file mode 100644 index 0000000..ecb950e --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02120___Navname.md @@ -0,0 +1,7 @@ +--- +Data: + Version: "ab v1.0" + +--- + +Dieser Wert überschreibt den aus dem Ordnernamen automatisch abgeleiteten Navigationspunkt-Namen. Dies ist zum Beispiel dann nützlich, wenn Sonderzeichen im Verzeichnisnamen nicht vorkommen sollen, aber im Namen des Navigationspunkts gebraucht werden. diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02130___Data.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02130___Data.md new file mode 100644 index 0000000..a167e66 --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02130___Data.md @@ -0,0 +1,8 @@ +--- +Data: + Version: "ab v1.0" + +--- + +Unterhalb von `Data:` können beliebige Datenstrukturen erfasst werden. Da diese Struktur unterhalb von `This:` angeordnet ist, werden auch die Daten nicht weiter an Unterordner vererbt. +Hier können z.B. Informationen zum Navigationspunkt abgelegt werden, die im Template Zusatzinformationen darstellen (z.B. ein Slogan zu einem Navigationspunkt). diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02200__Sektion Meta.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02200__Sektion Meta.md new file mode 100644 index 0000000..5e10f93 --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02200__Sektion Meta.md @@ -0,0 +1,17 @@ +--- +Data: + Version: "ab v1.0" + +--- + +Unter `Title:`, `Description:` und `Keywords:` werden die typischen Metaangaben abgelegt, die im + +```html + + ... + +``` + +übllicherweise Verwendung finden. Die entsprechenden Platzhalter stehen im Template zur Verfügung. + +`Meta:` vererbt seine individuellen Informationen an die Unterordner weiter, sofern diese dort nicht selbst in einer `config.yml` oder im Kopf der Markdown-Datei definiert sind. diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02300__Sektion Data.md b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02300__Sektion Data.md new file mode 100644 index 0000000..46889eb --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/_02300__Sektion Data.md @@ -0,0 +1,7 @@ +--- +Data: + Version: "ab v1.0" + +--- + +`Data:` an dieser Stelle kann, wie auch `Data:` unterhalb von `This:`, beliebige Daten aufnehmen. Die Daten hier allerdings werden an Unterordner weitervererbt, sofern diese nicht dort oder in der Markdown-Datei selbst festegelegt überschrieben wurden. diff --git a/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/config.yml b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/config.yml new file mode 100644 index 0000000..5e9d5ad --- /dev/null +++ b/website/content/de/01_Navigation/03_Dokumentation/02_Konfiguration/config.yml @@ -0,0 +1,9 @@ +This: + Data: + teaser: Globale Konfiguration und individuelle Content-Einstellungen + Collections: + - Name: doccoll + Directory: + Path: "." + MatchFilename: "^_\\d+(?P_*)(?P.+)\\.md" + ReverseOrder: False diff --git a/website/content/de/01_Navigation/03_Benutzung/03_Inhalte/README.md b/website/content/de/01_Navigation/03_Dokumentation/03_Inhalte/README.md similarity index 100% rename from website/content/de/01_Navigation/03_Benutzung/03_Inhalte/README.md rename to website/content/de/01_Navigation/03_Dokumentation/03_Inhalte/README.md diff --git a/website/content/de/01_Navigation/03_Benutzung/03_Inhalte/config.yml b/website/content/de/01_Navigation/03_Dokumentation/03_Inhalte/config.yml similarity index 100% rename from website/content/de/01_Navigation/03_Benutzung/03_Inhalte/config.yml rename to website/content/de/01_Navigation/03_Dokumentation/03_Inhalte/config.yml diff --git a/website/content/de/01_Navigation/03_Benutzung/04_Templates/README.md b/website/content/de/01_Navigation/03_Dokumentation/04_Templates/README.md similarity index 100% rename from website/content/de/01_Navigation/03_Benutzung/04_Templates/README.md rename to website/content/de/01_Navigation/03_Dokumentation/04_Templates/README.md diff --git a/website/content/de/01_Navigation/03_Benutzung/04_Templates/config.yml b/website/content/de/01_Navigation/03_Dokumentation/04_Templates/config.yml similarity index 100% rename from website/content/de/01_Navigation/03_Benutzung/04_Templates/config.yml rename to website/content/de/01_Navigation/03_Dokumentation/04_Templates/config.yml diff --git a/website/content/de/01_Navigation/03_Benutzung/config.yml b/website/content/de/01_Navigation/03_Dokumentation/config.yml similarity index 100% rename from website/content/de/01_Navigation/03_Benutzung/config.yml rename to website/content/de/01_Navigation/03_Dokumentation/config.yml diff --git a/website/project-files/css/main.css b/website/project-files/css/main.css index 5b735cb..78823a7 100755 --- a/website/project-files/css/main.css +++ b/website/project-files/css/main.css @@ -292,4 +292,14 @@ code.language-mermaid svg { border-radius: 5px; display:inline-block; color: #fff; +} + +.versionBadge { + text-align: right; + color: #444; + font-size: 10px; + padding: 3px; + background: #ddd; + border: #444 solid 1px; + border-radius: 5px; } \ No newline at end of file diff --git a/website/templates/base_doc.html b/website/templates/base_doc.html new file mode 100644 index 0000000..28a7262 --- /dev/null +++ b/website/templates/base_doc.html @@ -0,0 +1,19 @@ +{% extends 'base.html' %} + +{% block part0 %} + {{ Body }} +{% endblock part0 %} + +{% block part1 %} + {% for e in NavElement.ColMap.doccoll %} + {% with e.FilenameMatch.lowdash|count + 1 as h %} + <h{{ h }}> + {{ e.FilenameMatch.title }} + {% if e.Data.Version %} + <span class="versionBadge">{{ e.Data.Version }}</span> + {% endif %} + </h{{ h }}> + {% endwith %} + {{ e.Body }} + {% endfor %} +{% endblock part1 %} diff --git a/website/templates/filters/count.js b/website/templates/filters/count.js new file mode 100644 index 0000000..889b0bf --- /dev/null +++ b/website/templates/filters/count.js @@ -0,0 +1,5 @@ +function count(el, param) { + return el.length +} + +module.exports = count; \ No newline at end of file