1
0
mirror of https://github.com/danog/gojekyll.git synced 2024-11-27 03:24:40 +01:00
gojekyll/pages/permalinks.go

103 lines
2.9 KiB
Go
Raw Normal View History

2017-06-22 17:02:32 +02:00
package pages
2017-06-15 13:31:52 +02:00
import (
"fmt"
"path/filepath"
2017-06-15 16:17:21 +02:00
"regexp"
2017-06-22 18:56:08 +02:00
"sort"
2017-06-23 02:39:53 +02:00
"strconv"
"strings"
2017-06-17 01:17:22 +02:00
"github.com/osteele/gojekyll/constants"
2017-06-17 02:11:52 +02:00
"github.com/osteele/gojekyll/helpers"
2017-07-01 05:56:29 +02:00
"github.com/osteele/gojekyll/templates"
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
func (p *file) permalinkTemplateVariables() map[string]string {
2017-06-15 13:31:52 +02:00
var (
2017-06-22 16:37:31 +02:00
relpath = strings.TrimPrefix(p.relpath, p.container.PathPrefix())
root = helpers.TrimExt(relpath)
name = filepath.Base(root)
2017-06-22 18:56:08 +02:00
categories = p.categories()
2017-06-15 13:31:52 +02:00
)
2017-06-22 18:56:08 +02:00
sort.Strings(categories)
2017-07-01 05:56:29 +02:00
bindings := templates.VariableMap(p.frontMatter)
2017-06-22 18:56:08 +02:00
// TODO recognize category; list
2017-06-15 15:01:42 +02:00
vs := map[string]string{
2017-06-22 18:56:08 +02:00
"categories": strings.Join(categories, "/"),
2017-07-01 05:56:29 +02:00
"collection": bindings.String("collection", ""),
2017-06-17 02:11:52 +02:00
"name": helpers.Slugify(name),
"path": "/" + root,
2017-07-01 05:56:29 +02:00
"slug": bindings.String("slug", helpers.Slugify(name)),
"title": bindings.String("slug", helpers.Slugify(name)),
2017-06-23 02:39:53 +02:00
// The following aren't documented, but is evident
"output_ext": p.OutputExt(),
2017-06-23 20:57:28 +02:00
"y_day": strconv.Itoa(p.fileModTime.YearDay()),
2017-06-15 15:01:42 +02:00
}
for name, f := range permalinkDateVariables {
2017-06-23 20:57:28 +02:00
vs[name] = p.fileModTime.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
}
func (p *file) expandPermalink() (s string, err error) {
2017-07-01 05:56:29 +02:00
pattern := templates.VariableMap(p.frontMatter).String("permalink", constants.DefaultPermalinkPattern)
2017-06-15 13:31:52 +02:00
if p, found := PermalinkStyles[pattern]; found {
pattern = p
}
templateVariables := p.permalinkTemplateVariables()
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 {
2017-06-22 18:56:08 +02:00
panic(fmt.Errorf("unknown variable %q in permalink template %q", varname, pattern))
2017-06-15 13:31:52 +02:00
}
return value
})
2017-06-29 01:00:01 +02:00
return helpers.URLPathClean("/" + s), nil
2017-06-15 13:31:52 +02:00
}
// The permalink is computed once instead of on demand, so that subsequent
// access needn't check for an error.
func (p *file) initPermalink() (err error) {
p.permalink, err = p.expandPermalink()
return
}