diff --git a/docs/content/content/front-matter.md b/docs/content/content/front-matter.md index e61a48f55bc..4a7e13e698f 100644 --- a/docs/content/content/front-matter.md +++ b/docs/content/content/front-matter.md @@ -1,7 +1,7 @@ --- aliases: - /doc/front-matter/ -lastmod: 2015-12-23 +lastmod: 2017-06-29 date: 2013-07-01 menu: main: @@ -117,3 +117,12 @@ It's possible to set some options for Markdown rendering in the page's front mat See [Configuration]({{< ref "overview/configuration.md#configure-blackfriday-rendering" >}}) for more. +## Fallback date variable from filenames +If you're migrating content to Hugo, you may have content with dates in the filename. For example `2017-01-31-myblog.md`. You can optionally enable the `filenameDateFallbackPattern` and `filenameDateFallbackFormat` configuration options. These will allow you to fallback on datestamps provided in the filename in place of a date value in the front matter. + +As an example, for posts following a YYY-MM-DD-posttitle.md naming convention, you can use: + +``` +filenameDateFallbackPattern: "(?P\\d{4})\\-(?P\\d{2})\\-(?P\\d{2})" +filenameDateFallbackFormat: "2006-01-02" +``` diff --git a/docs/content/overview/configuration.md b/docs/content/overview/configuration.md index 7d05570b7c7..17ee3fd8587 100644 --- a/docs/content/overview/configuration.md +++ b/docs/content/overview/configuration.md @@ -1,7 +1,7 @@ --- aliases: - /doc/configuration/ -lastmod: 2016-09-17 +lastmod: 2017-04-09 date: 2013-07-01 linktitle: Configuration menu: @@ -139,6 +139,10 @@ along with their current, default values: enableEmoji: false # Show a placeholder instead of the default value or an empty string if a translation is missing enableMissingTranslationPlaceholders: false + # Regex to use for dates in filenames. + filenameDateFallbackPattern: "(?P\\d{4})\\-(?P\\d{2})\\-(?P\\d{2})" + # Time format for custom dates in filenames. Must match `filenameDateFallbackPattern` + filenameDateFallbackFormat: "2006-01-02" footnoteAnchorPrefix: "" footnoteReturnLinkContents: "" # google analytics tracking id diff --git a/hugolib/config.go b/hugolib/config.go index 189b593e6de..2cebf301222 100644 --- a/hugolib/config.go +++ b/hugolib/config.go @@ -108,6 +108,8 @@ func loadDefaultSettingsFor(v *viper.Viper) { v.SetDefault("enableEmoji", false) v.SetDefault("pygmentsCodeFencesGuessSyntax", false) v.SetDefault("useModTimeAsFallback", false) + v.SetDefault("filenameDateFallbackPattern", nil) + v.SetDefault("filenameDateFallbackFormat", "2006-01-02") v.SetDefault("defaultContentLanguage", "en") v.SetDefault("defaultContentLanguageInSubdir", false) v.SetDefault("enableMissingTranslationPlaceholders", false) diff --git a/hugolib/page.go b/hugolib/page.go index c63d416a807..cc0f2e5aee2 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -1021,6 +1021,14 @@ func (p *Page) update(f interface{}) error { p.Date = fi.ModTime() p.Params["date"] = p.Date } + } else if p.Date.IsZero() && p.s.Cfg.GetString("filenameDateFallbackPattern") != "" { + dateExp := regexp.MustCompile(p.s.Cfg.GetString("filenameDateFallbackPattern")) + dateString := dateExp.FindString(p.File.Path()) + filenameDate, err := time.Parse(p.s.Cfg.GetString("filenameDateFallbackFormat"), dateString) + if err == nil { + p.Date = filenameDate + p.Params["date"] = p.Date + } } if p.Lastmod.IsZero() { diff --git a/hugolib/page_test.go b/hugolib/page_test.go index d24bd2f96f1..596417d19ff 100644 --- a/hugolib/page_test.go +++ b/hugolib/page_test.go @@ -95,6 +95,7 @@ Content of the file goes Here Content of the file goes Here ` simplePageRFC3339Date = "---\ntitle: RFC3339 Date\ndate: \"2013-05-17T16:59:30Z\"\n---\nrfc3339 content" + simplePageNoDate = "---\ntitle: Path Date\n---\n Date param from url" simplePageJSONMultiple = ` { "title": "foobar", @@ -847,6 +848,22 @@ func TestPageWithDate(t *testing.T) { checkPageDate(t, p, d) } +func TestPageWithDateInFilename(t *testing.T) { + t.Parallel() + cfg, fs := newTestCfg() + + writeSource(t, fs, filepath.Join("content", "2017-01-31-simple.md"), simplePageNoDate) + + s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{SkipRender: true}) + + require.Len(t, s.RegularPages, 1) + + p := s.RegularPages[0] + d, _ := time.Parse(time.RFC3339, "2017-01-31") + + checkPageDate(t, p, d) +} + func TestWordCountWithAllCJKRunesWithoutHasCJKLanguage(t *testing.T) { t.Parallel() assertFunc := func(t *testing.T, ext string, pages Pages) {