diff --git a/README.md b/README.md index 84d68634..882227d3 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,10 @@ There are several ways to convey author-specific information. Author information The plugin exposes a helper tag to expose the appropriate meta tags to support automated discovery of your feed. Simply place `{% feed_meta %}` someplace in your template's `` section, to output the necessary metadata. +The helper can also generate the link for a given collection: `{% feed_meta my_collection %}` or a given category: `{% feed_meta my_collection my_category %}`. + +To generate links for every collections and categories, call the helper using this syntax: `{% feed_meta include: all %}`. + ### SmartyPants The plugin uses [Jekyll's `smartify` filter](https://jekyllrb.com/docs/templates/) for processing the site title and post titles. This will translate plain ASCII punctuation into "smart" typographic punctuation. This will not render or strip any Markdown you may be using in a title. diff --git a/lib/jekyll-feed/meta-tag.rb b/lib/jekyll-feed/meta-tag.rb index 8cb357da..d520127e 100644 --- a/lib/jekyll-feed/meta-tag.rb +++ b/lib/jekyll-feed/meta-tag.rb @@ -5,17 +5,26 @@ class MetaTag < Liquid::Tag # Use Jekyll's native relative_url filter include Jekyll::Filters::URLFilters + def initialize(tag_name, args, tokens) + super + @args = args + end + def render(context) @context = context - @generator = generator - links = [] - generator.collections.each do |collection, meta| - (meta["categories"] + [nil]).each do |category| - attrs = attributes(collection, category).map { |k, v| %(#{k}="#{v}") }.join(" ") - links << "" + if @args.strip == "include: all" + links = [] + generator.collections.each do |collection, meta| + (meta["categories"] + [nil]).each do |category| + links << link(collection, category) + end end + links.reverse.join "\n" + else + @collection, @category = @args.split(" ") + @collection ||= "posts" + link(@collection, @category) if valid_collection && valid_category end - links.reverse.join "\n" end private @@ -28,6 +37,11 @@ def generator @generator ||= @context.registers[:site].generators.select { |it| it.is_a? JekyllFeed::Generator }.first # rubocop:disable Metrics/LineLength end + def link(collection, category) + attrs = attributes(collection, category).map { |k, v| %(#{k}="#{v}") }.join(" ") + "" + end + def attributes(collection, category) href = absolute_url(generator.feed_path(:collection => collection, :category => category)) { @@ -41,5 +55,28 @@ def attributes(collection, category) def title config["title"] || config["name"] end + + def valid_collection + return true if generator.collections.key? @collection + + Jekyll.logger.warn( + "Jekyll Feed:", + "Invalid collection name. Please review `{% feed_meta #{@args} %}`" + ) + false + end + + def valid_category + return true if @collection == "posts" || @category.nil? + + collection = generator.collections[@collection] + return true if collection.key?("categories") && collection["categories"].include?(@category) + + Jekyll.logger.warn( + "Jekyll Feed:", + "Invalid category name. Please review `{% feed_meta #{@args} %}`" + ) + false + end end end diff --git a/spec/jekyll-feed_spec.rb b/spec/jekyll-feed_spec.rb index 94272816..68d3672d 100644 --- a/spec/jekyll-feed_spec.rb +++ b/spec/jekyll-feed_spec.rb @@ -269,32 +269,6 @@ expect(feed_meta).not_to include("title=") end end - context "with a collection" do - let(:overrides) do - { - "collections" => { - "collection" => { - "output" => true, - }, - }, - "feed" => { - "collections" => { - "collection" => { - "categories" => ["news"], - }, - }, - }, - } - end - it "renders a feed meta for each collection" do - default_feed = '' - collection_feed = '' - category_feed = '' - expect(feed_meta).to include(default_feed) - expect(feed_meta).to include(collection_feed) - expect(feed_meta).to include(category_feed) - end - end end context "changing the feed path" do @@ -339,6 +313,66 @@ end end + context "selecting a particular collection" do + let(:overrides) do + { + "collections" => { + "collection" => { + "output" => true, + }, + }, + "feed" => { + "collections" => { + "collection" => { + "categories" => ["news"], + }, + }, + }, + } + end + let(:default_feed) { Liquid::Template.parse("{% feed_meta posts %}").render!(context, {}) } + let(:collection_feed) { Liquid::Template.parse("{% feed_meta collection %}").render!(context, {}) } + let(:category_feed) { Liquid::Template.parse("{% feed_meta collection news %}").render!(context, {}) } + + it "renders the feed meta for the selected collection" do + default_feed_link = '' + collection_feed_link = '' + category_feed_link = '' + expect(default_feed).to eql(default_feed_link) + expect(collection_feed).to eql(collection_feed_link) + expect(category_feed).to eql(category_feed_link) + end + end + + context "requesting all feed links" do + let(:overrides) do + { + "collections" => { + "collection" => { + "output" => true, + }, + }, + "feed" => { + "collections" => { + "collection" => { + "categories" => ["news"], + }, + }, + }, + } + end + let(:full_feed_meta) { Liquid::Template.parse("{% feed_meta include: all %}").render!(context, {}) } + + it "renders the feed meta for all collections and categories" do + default_feed_link = '' + collection_feed_link = '' + category_feed_link = '' + expect(full_feed_meta).to include(default_feed_link) + expect(full_feed_meta).to include(collection_feed_link) + expect(full_feed_meta).to include(category_feed_link) + end + end + context "feed stylesheet" do it "includes the stylesheet" do expect(contents).to include('')