From beca42d5c92d3f2d42a32b73da61a891d7fe8bce Mon Sep 17 00:00:00 2001 From: Brett Kosinski Date: Mon, 2 Dec 2019 17:37:20 -0700 Subject: [PATCH 1/2] Support for user-configurable feed templates. This commit adds a new configuration setting that allows the user to specify their own feed template, either for all feeds, or for categories or collections, as follows: feed: ... templates: - path: feed-foo.xml collection: bar category: baz - path: feed-xyz.xml collection: bar - path: feed-qwe.xml category: baz - path: feed.xml For a given feed, the first matching template is the one that's used. --- lib/jekyll-feed/generator.rb | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/jekyll-feed/generator.rb b/lib/jekyll-feed/generator.rb index 13684056..e872538b 100644 --- a/lib/jekyll-feed/generator.rb +++ b/lib/jekyll-feed/generator.rb @@ -8,6 +8,8 @@ class Generator < Jekyll::Generator # Main plugin action, called by Jekyll-core def generate(site) @site = site + @feed_templates = {} + collections.each do |name, meta| Jekyll.logger.info "Jekyll Feed:", "Generating feed for #{name}" (meta["categories"] + [nil]).each do |category| @@ -69,13 +71,22 @@ def collections @collections end - # Path to feed.xml template file - def feed_source_path - @feed_source_path ||= File.expand_path "feed.xml", __dir__ - end - def feed_template - @feed_template ||= File.read(feed_source_path).gsub(MINIFY_REGEX, "") + def feed_template(collection, category) + feed_source_path = File.expand_path "feed.xml", __dir__ + + (config["templates"] || []).each do |entry| + if (! entry.key? "collection" or collection == entry["collection"]) and + (! entry.key? "category" or category == entry["category"]) + + feed_source_path = entry["path"] + break + end + end + + @feed_templates.fetch(feed_source_path) { + File.read(feed_source_path).gsub(MINIFY_REGEX, "") + } end # Checks if a file already exists in the site source @@ -87,7 +98,7 @@ def file_exists?(file_path) def make_page(file_path, collection: "posts", category: nil) PageWithoutAFile.new(@site, __dir__, "", file_path).tap do |file| - file.content = feed_template + file.content = feed_template(collection, category) file.data.merge!( "layout" => nil, "sitemap" => false, From b67ba5a59511bbe95acb776207e2f287b66828ce Mon Sep 17 00:00:00 2001 From: Brett Kosinski Date: Thu, 5 Dec 2019 10:52:27 -0700 Subject: [PATCH 2/2] Support for multiple main feeds. This change enables multiple main feeds with different layouts. --- lib/jekyll-feed/generator.rb | 62 +++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/lib/jekyll-feed/generator.rb b/lib/jekyll-feed/generator.rb index e872538b..ca1208c6 100644 --- a/lib/jekyll-feed/generator.rb +++ b/lib/jekyll-feed/generator.rb @@ -8,17 +8,52 @@ class Generator < Jekyll::Generator # Main plugin action, called by Jekyll-core def generate(site) @site = site + + @feeds = [] @feed_templates = {} - collections.each do |name, meta| - Jekyll.logger.info "Jekyll Feed:", "Generating feed for #{name}" - (meta["categories"] + [nil]).each do |category| - path = feed_path(:collection => name, :category => category) - next if file_exists?(path) + # Define the main feeds + (config["feeds"] || { nil => nil }).keys.each do |id| + @feeds << { :id => id || "posts", + :collection => "posts", + :category => nil } + end - @site.pages << make_page(path, :collection => name, :category => category) + # Define the collection/category autogenerated feeds + # + # Remember, this outer loop includes the "posts" collection. + collections.each do |collection, meta| + (meta["categories"] + [nil]).each do |category| + # This is the main feed and its covered above + next if collection == "posts" and category.nil? + + if collection == "posts" + id = "#{category}" + elsif category.nil? + id = "#{collection}" + else + id = "#{collection}/#{category}" + end + + @feeds << { :id => id, + :collection => collection, + :category => category } end end + + # Now generate the feeds + @feeds.each do |feed| + path = feed_path(:collection => feed[:collection], :category => feed[:category], :id => feed[:id]) + + Jekyll.logger.info "Jekyll Feed:", "Generating feed for #{feed[:id]} at #{path}" + + next if file_exists?(path) + + @site.pages << make_page(path, + feed[:collection], + :category => feed[:category], + :id => feed[:id]) + end end private @@ -43,11 +78,13 @@ def config # Will return `/feed/category.xml` for post categories # WIll return `/feed/collection.xml` for other collections # Will return `/feed/collection/category.xml` for other collection categories - def feed_path(collection: "posts", category: nil) + def feed_path(collection: "posts", category: nil, id: nil) prefix = collection == "posts" ? "/feed" : "/feed/#{collection}" return "#{prefix}/#{category}.xml" if category - collections.dig(collection, "path") || "#{prefix}.xml" + path = config.dig("feeds", id) || + collections.dig(collection, "path") || + "#{prefix}.xml" end # Returns a hash representing all collections to be processed and their metadata @@ -72,12 +109,13 @@ def collections end - def feed_template(collection, category) + def feed_template(collection, category, id) feed_source_path = File.expand_path "feed.xml", __dir__ (config["templates"] || []).each do |entry| if (! entry.key? "collection" or collection == entry["collection"]) and - (! entry.key? "category" or category == entry["category"]) + (! entry.key? "category" or category == entry["category"]) and + (! entry.key? "id" or id == entry["id"]) feed_source_path = entry["path"] break @@ -96,9 +134,9 @@ def file_exists?(file_path) # Generates contents for a file - def make_page(file_path, collection: "posts", category: nil) + def make_page(file_path, collection, category: nil, id: nil) PageWithoutAFile.new(@site, __dir__, "", file_path).tap do |file| - file.content = feed_template(collection, category) + file.content = feed_template(collection, category, id) file.data.merge!( "layout" => nil, "sitemap" => false,