From 20a6c91b8da22734b63aec356d4866e6ec510ba5 Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Sun, 27 Mar 2022 18:43:18 +0100 Subject: [PATCH] Add `site.feed.updated = latest_post` setting Primary uses cases: 1. Reduce deployment churn in repositories that hold a docsite in addition to source code. These repositories currently regenerate and find "changed" files to deploy on every commit, even when nothing in the Jekyll site was changed. The only artefact changing each time is `feed.xml`. For example: https://github.com/qunitjs/qunit/commits/gh-pages 2. Improve reproducibility of the build, as highlighted via https://github.com/jekyll/jekyll/pull/7187. By offering a choice that simply eliminates use of current time entirely, we do not even have to worry about mocking it. --- README.md | 11 +++++++++++ lib/jekyll-feed/feed.xml | 14 +++++++++++++- spec/jekyll-feed_spec.rb | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 342177bf..516fbef6 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,17 @@ feed: To note, you shouldn't have to do this unless you already have a feed you're using, and you can't or wish not to redirect existing subscribers. +### Updated timestamp + +By default, the feed will set `` to the current time at build time, as provided by Jekyll via `site.time`. + +Enable the `updated: latest_post` setting to use a deterministic value based on when the latest post was published or updated. (The [jekyll-last-modified-at](https://github.com/gjtorikian/jekyll-last-modified-at) plugin is supported to help provide post modification times). + +```yml +feed: + updated: latest_post +``` + ### Optional front matter The plugin will use the following post metadata, automatically generated by Jekyll, which you can override via a post's YAML front matter: diff --git a/lib/jekyll-feed/feed.xml b/lib/jekyll-feed/feed.xml index 9068836f..77457f28 100644 --- a/lib/jekyll-feed/feed.xml +++ b/lib/jekyll-feed/feed.xml @@ -6,7 +6,6 @@ Jekyll - {{ site.time | date_to_xmlschema }} {{ page.url | absolute_url | xml_escape }} {% assign title = site.title | default: site.name %} @@ -51,7 +50,20 @@ {% assign posts = posts | where_exp: "post", "post.draft != true" %} {% endunless %} {% assign posts = posts | sort: "date" | reverse %} + {% assign posts_limit = site.feed.posts_limit | default: 10 %} + + {% assign last_updated = nil %} + {% if site.feed.updated == "latest_post" %} + {% for post in posts limit: posts_limit %} + {% assign post_updated = post.last_modified_at | default: post.date %} + {% if last_updated == nil or post_updated > last_updated %} + {% assign last_updated = post_updated %} + {% endif %} + {% endfor %} + {% endif %} + {{ last_updated | default: site.time | date_to_xmlschema }} + {% for post in posts limit: posts_limit %} {% assign post_title = post.title | smartify | strip_html | normalize_whitespace | xml_escape %} diff --git a/spec/jekyll-feed_spec.rb b/spec/jekyll-feed_spec.rb index 41514d1f..c8e2abe5 100644 --- a/spec/jekyll-feed_spec.rb +++ b/spec/jekyll-feed_spec.rb @@ -118,6 +118,7 @@ context "parsing" do let(:feed) { RSS::Parser.parse(contents) } + let(:overrides) { { "time" => Time.parse("2018-12-31") } } it "outputs an RSS feed" do expect(feed.feed_type).to eql("atom") @@ -136,6 +137,24 @@ expect(feed.generator.version).to eql(Jekyll::VERSION) end + context "with site.feed.updated = latest_post" do + let(:overrides) do + { + "feed" => { + "updated" => "latest_post", + }, + } + end + + it "outputs the last post time" do + expect(feed.updated.content).to eql(Time.parse("2016-04-25")) + end + end + + it "outputs the current time" do + expect(feed.updated.content).to eql(Time.parse("2018-12-31")) + end + it "includes the items" do expect(feed.items.count).to eql(10) end