1
0
mirror of https://github.com/danog/gojekyll.git synced 2024-11-27 05:54:44 +01:00
gojekyll/permalinks.go

105 lines
2.8 KiB
Go
Raw Normal View History

2017-06-15 13:31:52 +02:00
package main
import (
"fmt"
2017-06-16 01:49:04 +02:00
"path"
2017-06-15 13:31:52 +02:00
"path/filepath"
2017-06-15 16:17:21 +02:00
"regexp"
"strings"
2017-06-15 15:01:42 +02:00
"time"
2017-06-15 13:31:52 +02:00
)
// PermalinkStyles defines built-in styles from https://jekyllrb.com/docs/permalinks/#builtinpermalinkstyles
var PermalinkStyles = map[string]string{
"date": "/:categories/:year/:month/:day/:title.html",
"pretty": "/:categories/:year/:month/:day/:title/",
"ordinal": "/:categories/:year/:y_day/:title.html",
"none": "/:categories/:title.html",
}
2017-06-15 15:01:42 +02:00
// permalinkDateVariables maps Jekyll permalink template variable names
// to time.Format layout strings
var permalinkDateVariables = map[string]string{
"month": "01",
"imonth": "1",
"day": "02",
"i_day": "2",
"hour": "15",
"minute": "04",
"second": "05",
"year": "2006",
"short_year": "06",
}
2017-06-15 16:17:21 +02:00
var templateVariableMatcher = regexp.MustCompile(`:\w+\b`)
2017-06-15 15:01:42 +02:00
// See https://jekyllrb.com/docs/permalinks/#template-variables
2017-06-15 13:31:52 +02:00
func permalinkTemplateVariables(path string, frontMatter VariableMap) map[string]string {
var (
collectionName string
localPath = path
ext = filepath.Ext(path)
outputExt = ext
2017-06-15 15:01:42 +02:00
root = path[:len(path)-len(ext)]
2017-06-15 13:31:52 +02:00
name = filepath.Base(root)
title = frontMatter.String("title", name)
)
switch {
case isMarkdown(path):
outputExt = ".html"
case ext == ".scss":
2017-06-15 13:31:52 +02:00
outputExt = ".html"
}
if val, found := frontMatter["collection"]; found {
collectionName = val.(string)
prefix := "_" + collectionName + "/"
if !strings.HasPrefix(localPath, prefix) {
panic(fmt.Errorf("Expected %s to start with %s", localPath, prefix))
}
2017-06-15 13:31:52 +02:00
localPath = localPath[len(prefix):]
root = root[len(prefix):]
2017-06-15 13:31:52 +02:00
}
2017-06-15 15:01:42 +02:00
vs := map[string]string{
2017-06-15 13:31:52 +02:00
"collection": collectionName,
"name": Slugify(name),
"path": "/" + root,
2017-06-16 01:49:04 +02:00
"title": title,
"slug": Slugify(name),
// TODO categories
// The following isn't documented, but is evident
2017-06-15 15:01:42 +02:00
"output_ext": outputExt,
}
d := time.Now() // TODO read from frontMatter or use file modtime
for name, f := range permalinkDateVariables {
vs[name] = d.Format(f)
2017-06-15 13:31:52 +02:00
}
2017-06-15 15:01:42 +02:00
return vs
2017-06-15 13:31:52 +02:00
}
2017-06-16 01:49:04 +02:00
func expandPermalinkPattern(pattern string, rel string, frontMatter VariableMap) (s string, err error) {
2017-06-15 13:31:52 +02:00
if p, found := PermalinkStyles[pattern]; found {
pattern = p
}
2017-06-16 01:49:04 +02:00
templateVariables := permalinkTemplateVariables(rel, frontMatter)
2017-06-15 13:31:52 +02:00
// The ReplaceAllStringFunc callback signals errors via panic.
// Turn them into return values.
defer func() {
if r := recover(); r != nil {
if e, ok := r.(error); ok {
err = e
} else {
panic(r)
}
}
}()
s = templateVariableMatcher.ReplaceAllStringFunc(pattern, func(m string) string {
varname := m[1:]
value, found := templateVariables[varname]
if !found {
panic(fmt.Errorf("unknown variable %s in permalink template %s", varname, pattern))
}
return value
})
2017-06-16 01:49:04 +02:00
return path.Clean(s), nil
2017-06-15 13:31:52 +02:00
}