Hugo: Make GroupByParamDate work with string params

Created on 20 Oct 2017  路  16Comments  路  Source: gohugoio/hugo

I'm trying to group some of my articles by date using the project_date param defined in the front matter, but can't make it work. I end up with a runtime error: index out of range error in the console.

According to the documentation, it should look like this:

{{ range .Data.Pages.GroupByParamDate "project_date" "2006" "desc"}}

Any thoughts?

Update: I was using version 0.26 and upgraded to 0.30.2 and still experiencing the issue.

Enhancement Keep Upstream

Most helpful comment

This is still a bug :)

All 16 comments

This is because the function does not convert the a timestamp string into a time.Time structure: https://gohugo.io/functions/time/

In my testing when I printf the value of the parameters I got:

date: time.Time{wall:0x0, ext:63642202692, loc:(time.Location)(nil)}
expirydate: time.Time{wall:0x0, ext:0, loc:(
time.Location)(nil)}
lastmod: time.Time{wall:0x0, ext:63642202692, loc:(time.Location)(nil)}
project_date: "2017-09-28T13:38:12Z"
publishdate: time.Time{wall:0x0, ext:63642202692, loc:(
time.Location)(nil)}

I found GroupByParamDate worked with all of the parameters that were time.Time format above.

I'm seeing the same problem with 0.32.4. Is there a workaround for this (other than not using GroupByParamDate)?

@timn For my project I remapped the field in the CMS to the date param which for some reason does get converted to a time.Time format by Hugo. Luckily for my purposes I didn't need the actually date field for anything else for I could override it with my param.

Not an awesome solution and no other workaround that I am aware of.

I'd love to fix this. I was able to locate the problem but I don't know enough Go to get started.

This issue has been automatically marked as stale because it has not had recent activity. The resources of the Hugo team are limited, and so we are asking for your help.
If this is a bug and you can still reproduce this error on the master branch, please reply with all of the information you have about it in order to keep the issue open.
If this is a feature request, and you feel that it is still relevant and valuable, please tell us why.
This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions.

This is still a bug. It's also not possible to sort a collection of a page resources and normal pages by a custom date field for the same reasons.

This issue has been automatically marked as stale because it has not had recent activity. The resources of the Hugo team are limited, and so we are asking for your help.
If this is a bug and you can still reproduce this error on the master branch, please reply with all of the information you have about it in order to keep the issue open.
If this is a feature request, and you feel that it is still relevant and valuable, please tell us why.
This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions.

This is still a bug :)

First, I'm unable to reproduce the runtime error: index out of range error today.

Second, Hugo treats a few(?) reserved page parameter and forces them to a time.Time type. All other date parsing and conversion is left to the front matter parsers.

JSON does _not_ support timestamps. They're all treated as strings. Don't use JSON.

YAML does support timestamps, but the go-yaml package does not and will not until they decide to create a v3 of the package. I was able to comment out that if block to get go-yaml to recognize timestamps.

TOML does support timestamps, and the BurntSushi toml package parses them correctly. :tada:

So, as of today, you need to use TOML front matter.

I'll leave this issue open and mark it as Upstream since go-yaml should support this but doesn't.

PS - If you want to see the type of a variable from a template, use {{ printf "%T" .Params.foodate }}.

@moorereason This is good info, but what if we could just cast a value to a time format in Hugo?

Hypothetically {{ asDate .Params.timestring }}

Hypothetically {{ asDate .Params.timestring }}

{{ time .Params.timestring }}

As of 0.67.0 it's still broken. I'm getting runtime error: index out of range [0] with length 0. Any updates on this?

Kia ora everyone!

I have had this issue for a while and thought that I'd create a project that replicates it with the latest 0.72.0.

  1. Clone the repo (a stripped down version of my blog) https://gitlab.com/Finnito/hugo-issue-example
  2. Ensure you are running 0.72.0
  3. Using hugo server head over to localhost:1313/photos/
  4. See the error runtime error: index out of range [0] with length 0
  5. The file controlling this view can be found in themes/hugo-finn/layouts/section/photos.html on line 51
 {{ range .Data.Pages.GroupByParamDate "photoDate" "2006-01" "desc" }}

As far as I can tell, this syntax respects the documentation: https://gohugo.io/templates/lists/#by-page-parameter-in-date-format.

I hope this helps someone track this down!

{{ range .Data.Pages.GroupByParamDate (time .Params.photoDate) "2006-01" "desc" }}

Front Matter Format|Example|Data Type
:--|:--|:--
JSON|"2020-06-17T07:04:36-04:00"|String
JSON|2020-06-17T07:04:36-04:00|Invalid
YAML|"2020-06-17T07:04:36-04:00"|String
YAML|2020-06-17T07:04:36-04:00|String
TOML|"2020-06-17T07:04:36-04:00"|String
TOML|2020-06-17T07:04:36-04:00|_Time_

Your front matter format is TOML, and you have quote-encapsulated the photoDate value, so Hugo treats it as a string. You have two options:

A) Cast the string to a time.Time structure using the time function as shown above.
B) Remove the quotation marks surrounding the date in your TOML front matter.

I suspect that the documentation was written against a working example with TOML front matter where the timestamp was not quote-encapsulated.

Comments...

  1. This has come up before.
  2. This demonstrates the need to code templates defensively when working with timestamps. Unless you have control over the front matter format and front matter values, you may or may not be working with a string. I have run into this before in another context.
  3. Personally, I take advantage of the fact that TOML date/time values are first class citizens, and never quote-encapsulate the date/time values.

EDIT: I thought I had option "A" working, but now it is not.

Ah, amazing. Thank you for catching that - I clearly hadn't read the TOML spec but I have had a look through it now.

I shall convert all my stuff to TOML and ensure I am not quoting date/time values in the future!

This is labeled "Upstream" which is partially correct. GroupByParamDate should work as designed with unquoted YAML timestamps when v3 of YAML support for the Go language is released.

But GroupByParamDate will continue to fail when front matter is JSON. I suspect that JSON as a front matter format is relatively infrequent today, but this may change if/when pages can be created from data.

My 50 cents without having read all the discussion above:

  • We have all of GroupByDate, GroupByPublishDate, GroupByExpiryDate (but not GroupByLastmod which is odd, I'll see if we can add that)
  • We have a way to map other date params into date, expiryDate etc.
  • Those dates have a meaning in Hugo (sorting, expiry etc.), so I recommend using them.ha

But I do understand that there will be other dates (eventDate ...) ...

That said, I would expect this to kind of work for both YAML and TOML, but if it doesn't we should consider trying to convert the string to date on the fly inside GroupByParamDate. If that becomes a big performance hit, we can cache the result.

Was this page helpful?
0 / 5 - 0 ratings