Problems use `where` with dates

I feel like I run into issues with dates at least once a month.

If I do a simple range in list template, every event I have list out just fine. So basically this:

{{ range .Data.Pages }}

My events have a Front Matter/Params variable called eventdate. If I try to only loop through events with eventdate in the future, the loop has zero iterations. Something like this:

{{ range where .Data.Pages (time ".Params.eventdate") "ge" now }}

However, if I just check to make sure the event isn’t “now”. then the events are all listed:

{{ range where .Data.Pages (time ".Params.eventdate") "!=" now }}

Since I’m using YAML Front Matter, I assume the date doesn’t get casted correctly by itself which is why I’m using the time function. Otherwise, nothing works at all.

Also, I have two test events. One has a date in the future and the other a date in the past. An example of a future date: 2017-12-12T19:00:00-05:00.

Any ideas?

Update:

Changing the Front Matter to TOML and removing the time function from the line makes this all work. So there’s something wrong in the YAML parser and/or the time function.

2 Likes

Why do you assume that? But note that it needs to be a YAML/TOML date and not a string.

Did I understand correctly that Hugo recognizes the date when it is typed in this format?
Example 2.22. Timestamps

canonical: 2001-12-15T02:59:43.1Z
iso8601: 2001-12-14t21:59:43.10-05:00
spaced: 2001-12-14 21:59:43.10 -5
date: 2002-12-14

I will put it this way:

If go-yaml parses it into a date, then Hugo will use it as a date:

That’s the issue. I’m using printf "%T" and it looks like I can’t get go-yaml to parse anything as a date yet. I’m going to try and use the library directly now and see if anything changes.

The time fuction does correctly parse the YAML string into a date, but it doesn’t work when using where. So with the following line, the time fuction isn’t getting the datetime string so it can’t parse it:

{{ range where .Data.Pages (time ".Params.eventdate") "ge" now }}

Until I can figure out or fix the YAML issue, using time would be a backup but that doesn’t work with where. The only other backup solution I can think of is to not use where, loop through the events and use an if block to determine which events to show.

I hope I figure this out, dates are kind of important. :slight_smile:

Hey @FelicianoTech, did you ever find a solution for this issue? I’m trying to do a similar thing—prevent a event from showing up in a list if it has already happened. Like you, i’m making use of a custom Front Matter parameter, “event_date”.

Looking at https://gohugohq.com/howto/compare-date-strings-in-hugo/ this is the closest i got to something that works:

{{ range .Pages.ByParam "event_date" }}
  {{ if (time .Params.event_date).After now }}
    ...
  {{ end }}
{{ end }}

I wanted to paginate, but, with with something like this, you end up with blank pages:

{{ range (.Paginator 6).Pages.ByParam "event_date" }}
  {{ if (time .Params.event_date).After now }}
    ...
  {{ end }}
{{ end }}

And attempting a where function in the range, instead of an if function after the range has begun, like this, only results in errors:

{{ range where (.Paginator 6).Pages (time .Params.event_date).After now }}
  ...
{{ end }}

But i think i’ve got my syntax wrong.

But perhaps others with benefit from the link above. It at least got me something working, albeit not exactly what i wanted.

I’ve done something similar for adding an “updated” tag on recently updated posts.

I compared the now.Unix and .Lastmod.Unix dates:

{{ if lt (sub (now.Unix) (.Lastmod.Unix)) 1209600 }}<span class="badge badge-secondary">New</span>{{ end }}

I don’t have time to make this more specific, though, but maybe you can use that methodology somehow.

Kind of.

I ended of loading my events via a datafile. The real problem was YAML unmarshalling for me. Going with TOML worked, even though it don’t prefer it. Hugo has had work done with YAML in the past year so perhaps sometime in the near future I’ll try to revert my events datafile back to YAML and see if it works now.

My entire website is open source so here’s what I did:

1 Like

That’s @Jonathan_Griffin, that’s a smart tip and i hope to use it in the future. In my case, i’m hitting a wall when it comes to evaluating time in a range, but it sounds like it’s just not possible at this time.

Thanks @FelicianoTech, i’m not able to use a datafile, since i need dedicated pages for my events. Perhaps in the future Hugo will accommodate evaluations of time in a range, but this may also be a somewhat fringe use-case.

For anyone else who may be struggling with a similar issue, here’s as far as i’ve gotten…

In my front matter, i include these fields:

event:
  start: "2019-03-19T17:33:08-05:00"
  end: "2019-03-19T18:33:08-05:00"

And in my template, this is my best attempt at a range:

{{ range where (.Pages.ByParam "event.start") (time .Params.event.start).After (now.AddDate 0 0 -1) }}
...things and stuff...
{{ else }}
...Sorry no events at this time...
{{ end }}

But it always throws this error:

at <.Params.event.start>: can't evaluate field After in type *errors.errorString

So, in the meantime, i’m doing this:

{{ range .Pages.ByParam "event.start" }}
  {{ if .Params.event.start }}
    {{ if (time .Params.event.start).After (now.AddDate 0 0 -1) }}
      ...things and stuff...
    {{ end }}
  {{ end }}
{{ else }}
  ...Sorry no events at this time...
{{ end }}

Please note that the else statement is actually useless for now, but this code does’t throw any errors either and at least it gets me some of the way.

1 Like

Thank you for this thread… As someone who works with event pages as well, I need to often get the end_date and filter by it or use it in conditionals to hide/show certain elements.

Recently, I have been trying to figure out how best to get all the future events, based off the end_date param. But since it is not considered a date until it is ran through (time .Params.end_date), it is not possible use it as a source for filtering in a where statement. :confused:

{{- $future_events := where $events (time .Params.end_date) "ge" now -}}

This is generally a problem on list templates (here is ours), where you are trying to show a list of events.

It’s a lot easier to work with .Params.end_date on a single event page, because you can easily transform the field and then use it as a date.