1
0
mirror of https://github.com/danog/gojekyll.git synced 2024-11-26 23:04:38 +01:00

Parse post filenames dates in local location

This commit is contained in:
Oliver Steele 2017-08-20 12:12:06 -04:00
parent eab849b27d
commit 3744beef32
7 changed files with 54 additions and 55 deletions

View File

@ -22,7 +22,7 @@ type Collection struct {
site Site
}
// Site is the interface a site provides to collections it contains.
// Site is the interface a site provides to its collections.
type Site interface {
Config() *config.Config
Exclude(string) bool
@ -31,6 +31,9 @@ type Site interface {
OutputExt(pathname string) string
}
const draftsPath = "_drafts"
const postsName = "posts"
// New creates a new Collection
func New(s Site, name string, metadata map[string]interface{}) *Collection {
return &Collection{
@ -54,12 +57,12 @@ func (c *Collection) AbsDir() string {
func (c *Collection) PathPrefix() string { return filepath.FromSlash("_" + c.Name + "/") }
// IsPostsCollection returns true if the collection is the special "posts" collection.
func (c *Collection) IsPostsCollection() bool { return c.Name == "posts" }
func (c *Collection) IsPostsCollection() bool { return c.Name == postsName }
// Output returns a bool indicating whether files in this collection should be written.
func (c *Collection) Output() bool { return templates.VariableMap(c.Metadata).Bool("output", false) }
// Pages is a list of pages. Pages in the Post collection are ordered by date.
// Pages is a slice of the collection's pages. Pages in the Post collection are ordered by date.
func (c *Collection) Pages() []pages.Page {
return c.pages
}
@ -91,6 +94,6 @@ func (c *Collection) ToLiquid() interface{} {
// PermalinkPattern returns the default permalink pattern for this collection.
func (c *Collection) PermalinkPattern() string {
defaultPattern := c.strategy().defaultPermalinkPattern()
return templates.VariableMap(c.Metadata).String("permalink", defaultPattern)
pattern := c.strategy().defaultPermalinkPattern()
return templates.VariableMap(c.Metadata).String("permalink", pattern)
}

View File

@ -10,8 +10,6 @@ import (
"github.com/osteele/gojekyll/utils"
)
const draftsPath = "_drafts"
// ReadPages scans the file system for collection pages, and adds them to c.Pages.
func (c *Collection) ReadPages() error {
if c.IsPostsCollection() && c.cfg.Drafts {
@ -24,30 +22,34 @@ func (c *Collection) ReadPages() error {
}
if c.IsPostsCollection() {
sort.Sort(pagesByDate{c.pages})
var prev pages.Page
for _, p := range c.pages {
p.FrontMatter()["previous"] = prev
if prev != nil {
prev.FrontMatter()["next"] = p
}
prev = p
}
if prev != nil {
prev.FrontMatter()["next"] = nil
}
addPrevNext(c.pages)
}
return nil
}
func addPrevNext(ps []pages.Page) {
const prevPageField = "previous"
const nextPageField = "next"
var prev pages.Page
for _, p := range ps {
p.FrontMatter()[prevPageField] = prev
if prev != nil {
prev.FrontMatter()[nextPageField] = p
}
prev = p
}
if prev != nil {
prev.FrontMatter()[nextPageField] = 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 {
var (
sitePath = c.cfg.Source
dir = filepath.Join(sitePath, dirname)
)
walkFn := func(filename string, info os.FileInfo, err error) error {
sitePath := c.cfg.Source
dir := filepath.Join(sitePath, dirname)
return filepath.Walk(dir, func(filename string, info os.FileInfo, err error) error {
if err != nil {
if os.IsNotExist(err) {
return nil
@ -63,17 +65,16 @@ func (c *Collection) scanDirectory(dirname string) error {
default:
return c.readPost(filename, utils.MustRel(dir, filename))
}
}
return filepath.Walk(dir, walkFn)
})
}
func (c *Collection) readPost(abs string, rel string) error {
siteRel := utils.MustRel(c.cfg.Source, abs)
strategy := c.strategy()
switch {
case !strategy.collectible(rel):
case !strategy.isCollectible(rel):
return nil
case strategy.future(rel) && !c.cfg.Future:
case strategy.isFuture(rel) && !c.cfg.Future:
return nil
}
pageDefaults := map[string]interface{}{
@ -81,7 +82,7 @@ func (c *Collection) readPost(abs string, rel string) error {
"permalink": c.PermalinkPattern(),
}
fm := templates.MergeVariableMaps(pageDefaults, c.cfg.GetFrontMatterDefaults(c.Name, siteRel))
strategy.addDate(rel, fm)
strategy.parseFilename(rel, fm)
f, err := pages.NewFile(c.site, abs, filepath.ToSlash(rel), fm)
switch {
case err != nil:

View File

@ -6,13 +6,13 @@ import (
"github.com/osteele/gojekyll/utils"
)
// A collectionStrategy encapsulates behavior differences between the _post
// collection and other collection.
// A collectionStrategy encapsulates behavior differences between the `_post`
// collection and other collections.
type collectionStrategy interface {
addDate(filename string, fm map[string]interface{})
collectible(filename string) bool
defaultPermalinkPattern() string
future(filename string) bool
isCollectible(filename string) bool
isFuture(filename string) bool
parseFilename(string, map[string]interface{})
}
func (c *Collection) strategy() collectionStrategy {
@ -24,25 +24,25 @@ func (c *Collection) strategy() collectionStrategy {
type defaultStrategy struct{}
func (s defaultStrategy) addDate(_ string, _ map[string]interface{}) {}
func (s defaultStrategy) collectible(filename string) bool { return true }
func (s defaultStrategy) future(filename string) bool { return false }
func (s defaultStrategy) parseFilename(string, map[string]interface{}) {}
func (s defaultStrategy) isCollectible(string) bool { return true }
func (s defaultStrategy) isFuture(string) bool { return false }
type postsStrategy struct{}
func (s postsStrategy) addDate(filename string, fm map[string]interface{}) {
func (s postsStrategy) parseFilename(filename string, fm map[string]interface{}) {
if t, title, found := utils.FilenameDate(filename); found {
fm["date"] = t
fm["title"] = title
}
}
func (s postsStrategy) collectible(filename string) bool {
func (s postsStrategy) isCollectible(filename string) bool {
_, _, ok := utils.FilenameDate(filename)
return ok
}
func (s postsStrategy) future(filename string) bool {
func (s postsStrategy) isFuture(filename string) bool {
t, _, ok := utils.FilenameDate(filename)
return ok && t.After(time.Now())
}

View File

@ -164,10 +164,8 @@ func (f *file) PostDate() time.Time {
if err == nil {
return t
}
default:
panic(fmt.Sprintf("expected a date %v", value))
}
panic("read posts should have set this")
return f.fileModTime
}
// Write applies Liquid and Markdown, as appropriate.

View File

@ -42,18 +42,15 @@ var templateVariableMatcher = regexp.MustCompile(`:\w+\b`)
// See https://jekyllrb.com/docs/permalinks/#template-variables
func (p *page) permalinkVariables() map[string]string {
var (
relpath = p.relpath
root = utils.TrimExt(relpath)
name = filepath.Base(root)
fm = p.frontMatter
bindings = templates.VariableMap(fm)
slug = bindings.String("slug", utils.Slugify(name))
date = p.fileModTime
dateField = bindings.String("date", "")
)
if dateField != "" {
relpath = p.relpath
root = utils.TrimExt(relpath)
name = filepath.Base(root)
fm = p.frontMatter
bindings = templates.VariableMap(fm)
slug = bindings.String("slug", utils.Slugify(name))
// date = p.fileModTime
date = p.PostDate().In(time.Local)
}
)
vars := map[string]string{
"categories": strings.Join(p.Categories(), "/"),
"collection": bindings.String("collection", ""),

View File

@ -18,7 +18,7 @@ func FilenameDate(s string) (t time.Time, title string, found bool) {
found = false
return
}
t, err := time.Parse(layout, base[:len(layout)])
t, err := time.ParseInLocation(layout, base[:len(layout)], time.Local)
if err != nil {
return
}

View File

@ -24,7 +24,7 @@ func TestFilenameDate(t *testing.T) {
d, title, found := FilenameDate("2017-07-02-post.html")
require.True(t, found)
require.Equal(t, "post", title)
require.Equal(t, timeMustParse("2017-07-02T00:00:00Z"), d)
require.Equal(t, timeMustParse("2017-07-02T00:00:00-04:00"), d)
_, _, found = FilenameDate("not-post.html")
require.False(t, found)