diff --git a/lib/jekyll-feed/generator.rb b/lib/jekyll-feed/generator.rb index 13684056..ca1208c6 100644 --- a/lib/jekyll-feed/generator.rb +++ b/lib/jekyll-feed/generator.rb @@ -8,15 +8,52 @@ class Generator < Jekyll::Generator # Main plugin action, called by Jekyll-core def generate(site) @site = site - 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) - @site.pages << make_page(path, :collection => name, :category => category) + @feeds = [] + @feed_templates = {} + + # Define the main feeds + (config["feeds"] || { nil => nil }).keys.each do |id| + @feeds << { :id => id || "posts", + :collection => "posts", + :category => nil } + end + + # 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 @@ -41,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 @@ -69,13 +108,23 @@ 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, 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"]) and + (! entry.key? "id" or id == entry["id"]) + + 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 @@ -85,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 + file.content = feed_template(collection, category, id) file.data.merge!( "layout" => nil, "sitemap" => false,