Parsing dates in templates


#1

I’m trying to build an online CV with Hugo, the idea being that each entry can have frontmatter like:

+++
title = "Company name"
startdate = "2012-07"
enddate = "2014-09-13"
+++

which can then be parsed by the the template to produce something like:

Company name
July 2012 to September 2014

However, I’m struggling to find a way to do this. I understand that Go templates do not allow you to access arbitrary functions (e.g. time.Parse) and that you must pass in the functions you need as a funcMap. I can’t find any way to do this inside Hugo - ideally it’d be possible to say

{{ parse .Params.startdate "January 2006"}}

but I have no idea how I can make the parse function available without actually modifying Hugo itself.

Any ideas?


#2

I take this from memory, but I’m pretty sure time.Parse isn’t available as a template function – neither from Go’s builtins nor Hugo. It could be added, of course, but I’m struggling with understanding the use case.

mydate.Format makes sense, but that is available.


#3
date = "2015-01-17"

and then

{{ .Date.Format "January 2006" }}

works fine, because the date field gets automatically cast to a Time.

However,

startdate = "2015-01-17"

and

{{ .Params.startdate.Format "January 2006" }}

does not work, because startdate remains a String rather than being cast to Time.

I have now discovered that you can do the following:

startdate = 2013-07-24T00:00:00Z

and

{{ .Params.startdate.Format "January 2006" }}

because TOML has native support for ISO8601 dates and they are parsed to a Time rather than a String. However, this isn’t ideal, because TOML only supports ‘full Zulu’ dates - you can’t write

startdate = 2013-07-24

In fact, this actually crashes Hugo with the following error:

ERROR: 2015/01/18 Error parsing page meta data for entry.md
ERROR: 2015/01/18 Near line 4, key 'startdate': Near line 5: Expected 'T' in ISO8601 datetime, but found '\n' instead.
ERROR: 2015/01/18 Near line 4, key 'startdate': Near line 5: Expected 'T' in ISO8601 datetime, but found '\n' instead.
CRITICAL: 2015/01/18 Errors rendering pages: Near line 4, key 'startdate': Near line 5: Expected 'T' in ISO8601 datetime, but found '\n' instead.

I can live with writing the ‘full Zulu’ dates for now, but I’d like to find a neater solution. Maybe the answer is that the TOML spec needs changing!


#4

For reference:

Coincidentally, similar discussions happened in Issue #235: format string as date on GitHub back on March 20, 2014.

@spf13 concluded that it was a good idea to implement a new dateFormat function for this purpose, and welcome a pull request.


#5

Fixed in


#6

I’m quite new to hugo and am getting the following error:

$ hugo version
Hugo Static Site Generator v0.14-DEV BuildDate: 2015-02-22T08:09:28Z

$ hugo server --theme=lanyon --buildDrafts
ERROR: 2015/02/25 template: theme/post/li.html:1:25: executing "theme/post/li.html" at <.Site.Params.DateFor...>: invalid value; expected string in theme/post/li.html

ERROR: 2015/02/25 Error while rendering page post/post/first.md: template: theme/post/single.html:5:47: executing “theme/post/single.html” at <.Site.Params.DateFor…>: invalid value; expected string

And something pretty similar with the beg theme too. I’ve tried all sorts but I’m not getting very far. Here is what I have:

+++
title = "About Hugo"
date        = "2013-06-21T11:27:27-04:00"
menu = "main"
+++

And I’ve tried:

date = "2013-06-21T11:27:27-04:00"
date = 2013-06-21T11:27:27-04:00
date = 2013-06-21
date = "2013-06-21"

With the beg theme I get:

$ hugo server --theme=beg --buildDrafts
ERROR: 2015/02/25 template: theme/_default/li.html:6:39: executing "theme/_default/li.html" at <.Site.Params.DateFor...>: invalid value; expected string in theme/_default/li.html

Any ideas? Thanks.


#7

You need a line in your config.toml to define the DateForm parameter:

[Params]
	DateForm = "Jan 2 2006"

#8

Yes that fixed it thanks. So does the toml precide over the yml? I already had:

Params:
  DateForm: "Mon, Jan 2, 2006"

#9

I used the TOML as an example, since that’s what I work with. If you had that in your config.yaml, it should have picked it up.

Did you have the default config.toml in your directory, alongside the YAML? I don’t know the rules that Hugo uses to pick config files if both are present.


#10

I’m new to Hugo and don’t really understand the DateForm parameter (in the config file).

In the theme, I have: {{ .Date.Format .Site.Params.DateForm }}.
In the config file: DateForm = "02 Jan 2006".

That displays the date as “Sunday, Jul 19, 2015”. Oddly enough, when I remove the DateForm parameter from the theme, it works correctly:

In theme: {{ .Date.Format "02 Jan 2006" }} generates “19 Jul 2015” on the website.

How can I use the DateForm parameter so it outputs “19 Jul 2015”?

Edit: DateForm seems to be working now after I’ve restarted the Hugo webserver a few times now. It seems that changes in the config file aren’t picked up while Hugo is running.


#11

Yes, the config file is only read on startup.


#12

is dateFormat working for multilingual?
I used the simple way: substr and index of data:

{{ substr .Params.tarih 8 2 }} {{ index $.Site.Data.aylar (substr .Params.tarih 5 2 ) }} {{ substr .Params.tarih 0 4 }}

My dates are in format YYYY-MM-DD
And I get “12 Ağustos 2008” in Turkish.


#13

Currently no.


#14

I was hoping to use time.Parse to automatically set the expiryDate in an events archetype. Something like…

archetypes/events.md:

+++
{{- $eventDate := (getenv "EVENT_DATE") }}
eventDate = "{{ $eventDate }}"
expiryDate = "{{ (time.Parse time.RFC3339 $eventDate).AddDate 0 0 1 }}"
+++

Then I could just:

$ EVENT_DATE="2017-10-26T:17:00-07:00" hugo new events/myevent.md

…and not have to worry about copy/paste errors.


#15

I’m pretty sure something like this will work:

expiryDate = "{{ (time $eventDate).Add (10 | duration "hour" ) }}"

#16

Thanks for the quick reply! I had tried (time $eventDate) and got a parse error, but looking back through my command history I found a typo in my date string. Doh!

Fixing that, using duration "hour", and formatting it back to the expected format works:

expiryDate = "{{ ((time $eventDate).Add (10 | duration "hour" )).Format "2006-01-02T15:04:05-07:00" }}"