I\'m not sure to get the liquid syntax to help me pull posts that were published during the same week as the build date. Is that possible?
There are simpler ways to
Before even giving this answer a second thought, consider the fact that, at the very least the first part of this answer doesn't really work, because jekyll is a static site generator and therefore the shown posts are relative to the last build date, which may not be the same as current date.
The second part of the answer goes a bit deeper into the idea of actually generating a list of "recent posts", rather than "posts from last week".
To basically explain the code in words: First we get current year
and current week
, then we loop through every post and compare current year
and current week
to the week
and year
of the post. If they match, the post is shown.
Show — Build Week:
{% assign currentYear = site.time | date: "%Y" %}
{% assign currentWeek = site.time | date: "%W" %}
{%- for post in site.posts -%}
{% assign postYear = post.date | date: "%Y" %}
{% assign postWeek = post.date | date: "%W" %}
{%- if currentYear == postYear and currentWeek == postWeek -%}
<a href="{{ post.url }}">{{ post.title }}</a>
{%- endif -%}
{%- endfor -%}
Show — Build Day and 6 Days Prior:
{% assign currentYear = site.time | date: "%Y" %}
{% assign currentDay = site.time | date: "%j" | plus: 0 %}
{% assign currentDay_minus_week = site.time | date: "%j" | minus: 7 %}
{%- for post in site.posts -%}
{% assign postYear = post.date | date: "%Y" %}
{% assign postDay = post.date | date: "%j" | plus: 0 %}
{%- if currentYear == postYear and postDay > currentDay_minus_week and postDay <= currentDay -%}
<a href="{{ post.url }}">{{ post.title }}</a>
{%- endif -%}
{%- endfor -%}
In an effort to sort of salvage this answer, though it already kind of veered off course.... I wrote this code with similar logic, but this time it gets the year
and week
of the latest post and shows all posts posted that year and that week.
This would be bulletproof in terms of showing something even if you keep building the site without making new posts. But it also just shows only one post, if your last post is the only post posted that week, which may be a bit dumb...
On the other hand, the simplest method for showing "recent posts" is probably just using the limit
and limit recent posts to like last 5 posts or something like that: {%- for post in site.posts limit: 5 -%}
Show — Latest Post Week:
{% assign latestPost_year = site.posts.first.date | date: "%Y" %}
{% assign latestPost_week = site.posts.first.date | date: "%W" %}
{%- for post in site.posts -%}
{% assign postYear = post.date | date: "%Y" %}
{% assign postWeek = post.date | date: "%W" %}
{%- if latestPost_year == postYear and latestPost_week == postWeek -%}
<a href="{{ post.url }}">{{ post.title }}</a>
{%- endif -%}
{%- endfor -%}
Show — Latest Post Day and 6 Days Prior
{% assign latestPost_year = site.posts.first.date | date: "%Y" %}
{% assign latestPost_day = site.posts.first.date | date: "%j" | plus: 0 %}
{% assign latestPost_day_minus_week = site.posts.first.date | date: "%j" | minus: 7 %}
{%- for post in site.posts -%}
{% assign postYear = post.date | date: "%Y" %}
{% assign postDay = post.date | date: "%j" | plus: 0 %}
{%- if latestPost_year == postYear and postDay > latestPost_day_minus_week and postDay <= latestPost_day -%}
<a href="{{ post.url }}">{{ post.title }}</a>
{%- endif -%}
{%- endfor -%}
The above solution works, but doesn't span years.
So I utilized the concepts and came up with a simpler and more flexible solution for filtering for a
timeframe
(which can be any variable time span of seconds, hours, days, weeks, or months). My solution has fewer variables, and less logic.
Liquid date/time
uses unix timestamp (%s = seconds since 1970
). So I kept the timeframe
in seconds and do the conversion for the length of time. 86400 = 1 day
, 604800 = 1 wk
, 2678400 = 31 days
, ... and so on.
The code also assumes your posts use last_modified_at
in your post frontmatter. You could substitute for post.date
if you're not.
List posts within last week
{% assign timeframe = 604800 %}
{% for post in site.posts %}
{% assign post_in_seconds = post.last_modified_at | date: "%s" | plus: 0 %}
{% assign recent_posts = "now" | date: "%s" | minus: timeframe %}
{% if post_in_seconds > recent_posts %}
<a href="{{ post.url }}">{{ post.title }}</a>
{% endif %}
{% endfor %}
List posts within timeframe and flag new or modified
This code will list all posts to within a limit and flag an posts as new or modified in timeframe
. Length of list is limited to maxposts
. Note: css class is designed to utilize Bootstrap, remove/edit to your liking.
timeframe
2419200 = seconds in 4 weeksmaxposts
= 10label_FOOBAR
just clean way to handle html with liquidExample Results with new/modified flags & dates
Code
{% assign timeframe = 2419200 %}
{% assign maxposts = 10 %}
{% assign date_format = site.minima.date_format | default: "%m/%d" %}
<ul class="post-list text-muted list-unstyled">
{% for post in site.posts limit: maxposts %}
{% assign post_in_seconds = post.last_modified_at | date: "%s" | plus: 0 %}
{% assign recent_posts = "now" | date: "%s" | minus: timeframe %}
{% assign post_updated = post.last_modified_at | date: date_format %}
{% capture post_date %}<small>{{ post.date | date: date_format }}</small>{% endcapture %}
{% if post_in_seconds > recent_posts %}
{% capture label_new %}<span class="label label-primary">new</span>{% endcapture %}
{% if post.last_modified_at > post.date %}
{% assign label_new = '' %}{% comment %}Clear NEW if modified{% endcomment %}
{% capture label_updated %}<span class="label label-info">Updated <span class="badge">{{ post_updated }}</span></span>{% endcapture %}
{% endif %}
{% endif %}
<li>
<h4>{{ post_date }}
<a class="post-link" href="{{ post.url | relative_url }}">
{{ post.title | escape }}</a> {{ label_new }}{{ label_updated }}
</h4>
</li>
{% assign post_date = '' %}
{% assign label_updated = '' %}
{% endfor %}
</ul>
You never know when Jekyll builds, so Jekyll should output a big(ger) list of posts. You can use the code of Joonas for this. Then you should use javascript to hide the non-relevant posts (those older than one week).
This can easily be done by adding a custom attribute to your list, like this:
<li date="{{ post.date }}">{{ post.title }}</li>
Use jQuery (or vanilla js) to hide old posts:
// loop through all list items with a date
$('li[date]').each(function(){
// create a postDate in a date object
var postDate = new Date($(this).attr('date'));
// create an object with the date of one week ago
var oneWeekAgo = new Date();
oneWeekAgo.setDate(oneWeekAgo.getDate() - 7);
// compare dates and hide old posts
if(postDate<oneWeekAgo) $(this).hide();
});