-
-
Notifications
You must be signed in to change notification settings - Fork 7.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Work In Progress: hugolib: Extract date and slug from filename #4436
Conversation
af20b02
to
3314a40
Compare
@vassudanagunta does my description above make sense for this particular case? I'm not sure about the config, but it can maybe force a cleaner implementation. We use [frontmatter]
defaultDate = ["filename"] |
@bep the description makes sense. It looks like you're choosing something more future-proof than a boolean setting for this which I obviously love :)
I agree that whichever one you choose, it would be good to be consistent in the docs and API. Which mental model makes the docs easier to write and understand? I think I prefer "default" to "fallback", because they mean the same thing and "default" is already used in many other places:
or perhaps the following because you can pluralize "default" (I see why you want that):
btw, you can add many of the other issues/PRs I reference in #4341 to your Closes list. Is |
Yes, or at least for all the dates for starters. The code I committed is just the first start, I will ping you when there is something to look at. ´defaultDate` is a better name, thanks. |
bcb92ab
to
7f897ed
Compare
@vassudanagunta if I could pick your brain: There are currently some failing tests: --- FAIL: TestMetadataDates (0.17s)
page_test.go:1097: test 4, Date is: 2018-02-22 11:02:34.215129233 +0100 CET m=+0.040275985. Expected: 1969-01-10 09:17:42 +0000 UTC
page_test.go:1097: test 4, LastMod is: 2018-02-22 11:02:34.215129233 +0100 CET m=+0.040275985. Expected: 1969-01-10 09:17:42 +0000 UTC
page_test.go:1097: test 4, param date is: 2018-02-22 11:02:34.215129233 +0100 CET m=+0.040275985. Expected: 1969-01-10 09:17:42 +0000 UTC
page_test.go:1097: test 8, Date is: 2018-02-22 11:02:34.259801735 +0100 CET m=+0.084947146. Expected: 1969-01-10 09:17:42 +0000 UTC
page_test.go:1097: test 8, param date is: 2018-02-22 11:02:34.259801735 +0100 CET m=+0.084947146. Expected: 1969-01-10 09:17:42 +0000 UTC
page_test.go:1097: test 16, PubDate is: 2018-02-22 11:02:34.338479224 +0100 CET m=+0.163622275. Expected: 0001-01-01 00:00:00 +0000 UTC
page_test.go:1097: test 16, param publishdate is: 2018-02-22 11:02:34.338479224 +0100 CET m=+0.163622275. Expected: 0001-01-01 00:00:00 +0000 UTC
page_test.go:1097: test 17, PubDate is: 2018-02-22 11:02:34.346865549 +0100 CET m=+0.172008349. Expected: 0001-01-01 00:00:00 +0000 UTC
page_test.go:1097: test 17, param publishdate is: 2018-02-22 11:02:34.346865549 +0100 CET m=+0.172008349. Expected: 0001-01-01 00:00:00 +0000 UTC These are all related to to the But the behaviour for is now at least algorithmic with loops and stuff, and easier to understand and change than a massive if/else/switch. To sum up. In order, this is what happens:
The above means that My main question is the 1): I'm tempted to keep it as it is now, in this PR (and adjust tests) as it is pretty easy to reason about. And it fits with the semantics (at least for the filename fallback): It is the author date (not last modified or anything else). |
This commit adds a new config option which, when enabled and no date is set in front matter, will make Hugo try to parse the date from the content filename. Also, the filenames in these cases will make for very poor permalinks, so we will also use the remaining part as the page `slug` if that value is not set in front matter. This should make it easier to move content from Jekyll to Hugo. To enable, put this in your `config.toml`: ```toml [frontmatter] defaultDate = ["filename"] ``` Fixes gohugoio#285 Closes gohugoio#3310 Closes gohugoio#3762 Closes gohugoio#4340
@bep of course.
Buddy, I'm with you. I think the use of the file system's modification timestamp is problematic:
As such, despite similarities in name, I don't think the file's modification timestamp should be treated as synonymous with the LastMod front matter value. LastMod thus has a reliable, meaningful value, either explicitly set, or synced to Git's author date, which has stable semantics. From the docs:
But in your new logic, as Tests 4 and 8 show, the file's modification timestamp takes precedence over PublishDate as the default Date. I'm not sure the timestamp should be used at all, but certainly it shouldn't beat out a more reliable and explicitly set value. Likewise, I'm not sure PublishDate should ever be set to the file's modification timestamp (tests 16 and 17). The following "copy" precedence:
A value of |
@bep I recommend merging PR #4340. I think the test enhancements are germane to this effort. See 1cea4d3 for a full description of the commit. I just rebased it, and updated it as follows:
Also, rather than disabling test cases to get the test suite to pass, simply change the symbol in the "output" column of the test case. The point of the table is to visualize various cases of missing values and how it gets filled. You could, for example, if you agreed with my "copy" precedences above, with near zero effort quickly change the tests to match. Also, the framework has support for filename based dates. To test how it would interact with the other dates, simply uncomment these lines and modify the output column values: |
@vassudanagunta the "file system's modification timestamp" is deprecated and will be removed in a couple of Hugo versions, so I'm not spending philosophical time on that. Could you revise your comments above and ignore (forget about it, pretend it's not there) the "useModTimeAsFallback"? |
@bep I'm totally down to take it out. But are you sure you want to take it out altogether? See #2239. Below is what I think, based on the semantics of these fields, whichever way you decide re If useModTimeAsFallback is removed:
If useModTimeAsFallback remains an option:
|
Once done with these changes, can someone explain the change in 69b97b2. I find that change concerning for my use case.. I depend on the publishdate to be always non-nil i.e. If publishdate is not set, it should take date's value. Seems like, that commit now stops that from happening now? |
@@ -1059,6 +1113,9 @@ func TestMetadataDates(t *testing.T) { | |||
checkDate(t, i+1, "LastMod", p.ExpiryDate, test.expExp, fi) | |||
|
|||
// check Page Params | |||
// TODO(bep) we need to rewrite these date tests to more unit style. | |||
// The params checks below are currently flawed, as they don't check for the | |||
// absense (nil) of a date. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed this in PR #4340. Please see my comment on why you really should just merge it.
I'm not sure what you mean by "more unit style". I don't think you mean tests of smaller "units" such as an individual functions. What I did with these tests is to cover "the complex" that governs date values (front matter, filenames, file timestamps)... the "unit" is the blackbox the is Hugo's content processing. Or perhaps the table of inputs and outputs don't seem unit style to you? But that table is the data for data-driven unit tests. Inputs and outputs stripped of all the scaffolding code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A creating a site, then do a full build, and check the result will by most people categorised as an integration test. We do that a lot in Hugo, because building all is often cheaper/easier than creating testable and smaller units. My new frontmatterHandler
has no dependencies to Page
or Site
and can be tested as an unit.
To all of you, please stop with this on-going commentary of my code. The PR is clearly marked IN PROGRESS in two places. |
OK, some hours skiing have (maybe) created some clarity in my head about all of this. I think my hesitation to adding more config has been hiding the obvious solution. Quickly illustrated by its default (what you get when doing nothing): [frontmatter]
date = ["date", "publishDate", "lastMod"]
lastMod = ["lastMod", "date"]
publishDate = ["publishDate", "date"]
expiryDate = ["expiryDate"]
And custom config may look like this: [frontmatter]
date = ["date", "filename", "publishDate", "lastMod"]
lastMod = ["lastMod", "modTime", "date"] This should also solve #3977 There is also the Too complex? @kaushalmodi @vassudanagunta |
A quick note to the above:
|
Reads like plain English to me :) 👍 |
It's exactly what I've been recommending all along.
I've incorporated all of the above thoughts below. I've including some items that are out-of-scope for this PR because they test the flexibility of the design:
|
Yes, but it isn't "front matter", so that will have to wait.
Let me say it this way: If you add a custom setting, all must be specificed, so:
Is allowed, but that will be limiting (files without date pattern will not get a date). By adding "magic logic" to the above, you will be back to the "if then else" spaghetti we already had, which was hard to explain and understand. |
It's not magic or hard to understand if the semantics are about customizing default values, e.g. what Say your [frontmatter.defaults]
publishDate = ["date"]
title = ["<filename>"]
copyrightYear = ["<publishDate>"] and your ---
title: How to Customize Hugo Front Matter Default Values
date: 2017-12-27
publishDate: 2018-01-01
copyrightYear: 2017
---
content What would you expect the post's title, publishDate and copyrightYear to be? Which behavior would be harder to understand? |
This is about four specific dates (see above). Not about |
When walking, driving, skiing or designing, it is better to look ahead than at the ground immediately in front of you. I've said all I can say. All yours. |
I will postpone this until some later time, as I can see that we're on different pages. I will let this sit for a while. But the "predisposed plan" is to find a way to tell Hugo where to pick the values for these 4 fields: type PageDates struct {
Date time.Time
Lastmod time.Time
PublishDate time.Time
ExpiryDate time.Time
} In my head talking about "default values for front matter params" is giving false expectations. Given: date = ["date", "publishDate", "lastMod"] We could remove "date" and specify that as a hardcoded default, but that would (I think) give away flexibility and clarity for a slightly less verbose config. I agree that it could be useful to create a mapping for other front matter parameters, too, but default values should be handled in the templates (use the As a slightly stupid example, having this as a default setting would be really surprising (to me): [frontmatter]
defaultColor = ["blue"] Which I can guarantee that someone will try if the above was the naming scheme. |
The spec can be made tighter. I agree that adding this feature will give people to try illogical things and open unnecessary bug reports and discussions. How about this spec?:
Example of a valid configuration: [frontmatter]
date = ["publishDate", "lastMod"] # date (implied) > publishDate > lastMod
lastMod = ["date"] # lastMod (implied) > date
publishDate = ["date"] # publishDate (implied) > date |
@kaushalmodi, |
Right, I was just giving my perspective of a non-Go coder :) |
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
This commit adds a new config option which, when enabled and no date is set in front matter, will make Hugo try to parse the date from the content filename.
Also, the filenames in these cases will make for very poor permalinks, so we will also use the remaining part as the page
slug
if that value is not set in front matter.This should make it easier to move content from Jekyll to Hugo.
To enable, put this in your
config.toml
:Fixes #285
Closes #3310