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:
parent
eab849b27d
commit
3744beef32
@ -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)
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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", ""),
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user