From 9d95f0391716ab9225a2ba46a1a060ac77d52f79 Mon Sep 17 00:00:00 2001 From: Oliver Steele Date: Mon, 10 Jul 2017 13:54:52 -0400 Subject: [PATCH] Use date from post filename in permalink --- collection/collection.go | 14 ++--------- collection/read.go | 50 ++++++++++++++++++++-------------------- pages/page.go | 7 +++--- pages/permalinks.go | 19 +++++++++------ site/site.go | 4 ++-- 5 files changed, 45 insertions(+), 49 deletions(-) diff --git a/collection/collection.go b/collection/collection.go index 6b9c078..4ef92d8 100644 --- a/collection/collection.go +++ b/collection/collection.go @@ -22,6 +22,7 @@ type Collection struct { // Site is the interface a site provides to collections it contains. type Site interface { Config() *config.Config + Exclude(string) bool RenderingPipeline() pipelines.PipelineInterface OutputExt(pathname string) string } @@ -36,22 +37,11 @@ func New(s Site, name string, metadata map[string]interface{}) *Collection { } } -// AbsDir is in the page.Container interface. +// AbsDir returns the absolute path to the collection directory. func (c *Collection) AbsDir() string { return filepath.Join(c.config.SourceDir(), c.PathPrefix()) } -// Config is in the page.Container interface. -func (c *Collection) Config() *config.Config { - return c.config -} - -// OutputExt is in the page.Container interface. -func (c *Collection) OutputExt(pathname string) string { - return c.site.OutputExt(pathname) -} - -// PathPrefix is in the page.Container interface. // PathPrefix returns the collection's directory prefix, e.g. "_posts/" func (c *Collection) PathPrefix() string { return filepath.FromSlash("_" + c.Name + "/") } diff --git a/collection/read.go b/collection/read.go index a1166ae..ac99284 100644 --- a/collection/read.go +++ b/collection/read.go @@ -4,7 +4,6 @@ import ( "os" "path/filepath" "sort" - "strings" "github.com/osteele/gojekyll/pages" "github.com/osteele/gojekyll/templates" @@ -13,8 +12,26 @@ import ( const draftsPath = "_drafts" -// ScanDirectory scans the file system for collection pages, and adds them to c.Pages. -func (c *Collection) ScanDirectory(dirname string) error { +// ReadPages scans the file system for collection pages, and adds them to c.Pages. +func (c *Collection) ReadPages() error { + if c.IsPostsCollection() && c.config.Drafts { + if err := c.scanDirectory(draftsPath); err != nil { + return err + } + } + if err := c.scanDirectory(c.PathPrefix()); err != nil { + return err + } + if c.IsPostsCollection() { + sort.Sort(pagesByDate{c.pages}) + } + return nil +} + +// scanDirectory scans the file system for collection pages, and adds them to c.Pages. +// +// This function is distinct from ReadPages so that the posts collection can call it twice. +func (c *Collection) scanDirectory(dirname string) error { sitePath := c.config.Source pageDefaults := map[string]interface{}{ "collection": c.Name, @@ -29,35 +46,18 @@ func (c *Collection) ScanDirectory(dirname string) error { } relname := utils.MustRel(sitePath, filename) switch { - case strings.HasPrefix(filepath.Base(relname), "."): - return nil - case err != nil: - return err case info.IsDir(): return nil + case c.site.Exclude(relname): + return nil + default: + fm := templates.MergeVariableMaps(pageDefaults, c.config.GetFrontMatterDefaults(c.Name, relname)) + return c.readFile(filename, relname, fm) } - fm := templates.MergeVariableMaps(pageDefaults, c.config.GetFrontMatterDefaults(c.Name, relname)) - return c.readFile(filename, relname, fm) } return filepath.Walk(filepath.Join(sitePath, dirname), walkFn) } -// ReadPages scans the file system for collection pages, and adds them to c.Pages. -func (c *Collection) ReadPages() error { - if c.IsPostsCollection() && c.config.Drafts { - if err := c.ScanDirectory(draftsPath); err != nil { - return err - } - } - if err := c.ScanDirectory(c.PathPrefix()); err != nil { - return err - } - if c.IsPostsCollection() { - sort.Sort(pagesByDate{c.pages}) - } - return nil -} - // readFile mutates fm. func (c *Collection) readFile(abs string, rel string, fm map[string]interface{}) error { strategy := c.strategy() diff --git a/pages/page.go b/pages/page.go index b75638f..d378167 100644 --- a/pages/page.go +++ b/pages/page.go @@ -71,12 +71,13 @@ func (p *page) FrontMatter() map[string]interface{} { } // PostDate is part of the Page interface. -func (p *page) PostDate() time.Time { - switch value := p.frontMatter["date"].(type) { +// FIXME move this back to Page interface, or re-work this entirely. +func (f *file) PostDate() time.Time { + switch value := f.frontMatter["date"].(type) { case time.Time: return value case string: - t, err := evaluator.ParseTime(value) + t, err := evaluator.ParseDate(value) if err == nil { return t } diff --git a/pages/permalinks.go b/pages/permalinks.go index f106862..caf7e53 100644 --- a/pages/permalinks.go +++ b/pages/permalinks.go @@ -41,13 +41,18 @@ var templateVariableMatcher = regexp.MustCompile(`:\w+\b`) // See https://jekyllrb.com/docs/permalinks/#template-variables func (f *file) permalinkVariables() map[string]string { var ( - relpath = f.relpath - root = utils.TrimExt(relpath) - name = filepath.Base(root) - fm = f.frontMatter - bindings = templates.VariableMap(fm) - slug = bindings.String("slug", utils.Slugify(name)) + relpath = f.relpath + root = utils.TrimExt(relpath) + name = filepath.Base(root) + fm = f.frontMatter + bindings = templates.VariableMap(fm) + slug = bindings.String("slug", utils.Slugify(name)) + date = f.fileModTime + dateField = bindings.String("date", "") ) + if dateField != "" { + date = f.PostDate() + } vars := map[string]string{ "categories": strings.Join(f.Categories(), "/"), "collection": bindings.String("collection", ""), @@ -60,7 +65,7 @@ func (f *file) permalinkVariables() map[string]string { "y_day": strconv.Itoa(f.fileModTime.YearDay()), } for k, v := range permalinkDateVariables { - vars[k] = f.fileModTime.Format(v) + vars[k] = date.Format(v) } return vars } diff --git a/site/site.go b/site/site.go index 6e04185..286308b 100644 --- a/site/site.go +++ b/site/site.go @@ -190,10 +190,10 @@ func (s *Site) Exclude(path string) bool { exclusionMap := utils.StringArrayToMap(s.config.Exclude) base := filepath.Base(path) switch { - case inclusionMap[path]: - return false case path == ".": return false + case inclusionMap[path]: + return false case exclusionMap[path]: return true case strings.HasPrefix(base, "."), strings.HasPrefix(base, "_"):