Jack L.
Jack L.

Reputation: 1335

Jekyll using pipe operator in where_exp

I am using Jekyll 3.8. My posts contain date attribute set. Some of them contain values from the past (e.g. 2001-01-01), some of them from the future (e.g. 2109-12-31).

What I would like to achieve is to display only posts that are in the past (so that their date is smaller than now). Now, I've managed to get it done using:

{% capture current_time %}{{'now' | date: '%s'}}{% endcapture %}

{% for post in site.posts %}
  {% capture post_time %}{{post.date | date: '%s'}}{% endcapture %}
  {% if post_time >= current_time %}
           DISPLAY THE ITEM
  {% endif %}
{% endfor %}

but it's not efficient.

I would like to have it done using where_exp filter. Now - is it possible? My draft looks like:

{% capture current_time %}{{'now' | date: '%s'}}{% endcapture %}
{% assign filtered_posts = site.posts| where_exp:"post","post.date | date: '%s' >= current_time" %}

{% for post in filtered_posts %}
   DISPLAY THE ITEM
{% endfor %}

but I'm receiving Liquid Exception: Liquid error (line 5): comparison of Time with String failed in source.md.

I suppose, that the problem lies in | date: '%s' from {% assign filtered_posts = site.posts| where_exp:"post","post.date | date: '%s' >= current_time" %}.

Therefore:

  1. can I even use filters (pipe) in the where_exp expressions?
  2. If not, then - can I somehow cast the post.date to string without filters, or cast current_time to string and make the comparision work at the same time?

Upvotes: 1

Views: 929

Answers (2)

mcnesium
mcnesium

Reputation: 1513

I had a similar problem, which I described in detail in the Jekyll community forum. It is about getting a list of future events including today, and the OP's similar approach did not work here as well:

{% assign events_list = site.events | where_exp: "event", "event.date >= site.time | date: %F" %}

So I created a filter plugin in _plugins/to_time.rb, which converts a string to a Time object:

module Jekyll
    module AssetFilter
        def to_time(date_string)
            DateTime.parse(date_string).to_time
        end
    end
end

Liquid::Template.register_filter(Jekyll::AssetFilter)

This first parses the string to a DateTime object and then uses this to_time function to make a Time object.

Then I assign a variable with the current time, apply the pipe operator with the filter I need, and then I add the to_time filter in the end:

{% assign today = 'now' | date: '%F' | to_time %}

Using now, then using %F to just get the date part of it, then converting it back to Time, so today will be todays date at 0:00 in the morning.

Then I can compare it with the date object from my events collection items:

{% assign events_list = site.events | where_exp: "event", "event.date >= today" %}

Upvotes: 2

David Jacquel
David Jacquel

Reputation: 52789

I cannot reproduce your error as where_exp is throwing an error because of the pipe in the comparison expression.

Nevertheless, you can compare post.date which is a Time object to site.time (generation time) to get posts that are in the past.

{% assign filtered_posts = site.posts | where_exp: "post","post.date <= site.time" %}

Upvotes: 1

Related Questions