From 60c29561f270b15e861fb4b7b2ccb37442fd99f6 Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Tue, 12 Aug 2014 11:50:02 -0400 Subject: [PATCH 1/5] Use plural 'type' in front matter defaults for pages/posts/drafts Fixes #2657 --- lib/jekyll/convertible.rb | 6 ++--- lib/jekyll/deprecator.rb | 17 +++++++++---- lib/jekyll/frontmatter_defaults.rb | 41 +++++++++++++++++++++++++----- site/_docs/configuration.md | 15 +++++------ 4 files changed, 57 insertions(+), 22 deletions(-) diff --git a/lib/jekyll/convertible.rb b/lib/jekyll/convertible.rb index 8977ed94..68cb2b2a 100644 --- a/lib/jekyll/convertible.rb +++ b/lib/jekyll/convertible.rb @@ -129,11 +129,11 @@ module Jekyll # Returns the type of self. def type if is_a?(Post) - :post + :posts elsif is_a?(Page) - :page + :pages elsif is_a?(Draft) - :draft + :drafts end end diff --git a/lib/jekyll/deprecator.rb b/lib/jekyll/deprecator.rb index 031444c5..8e4daf9c 100644 --- a/lib/jekyll/deprecator.rb +++ b/lib/jekyll/deprecator.rb @@ -1,6 +1,8 @@ module Jekyll module Deprecator - def self.process(args) + extend self + + def process(args) no_subcommand(args) arg_is_present? args, "--server", "The --server command has been replaced by the \ 'serve' subcommand." @@ -16,24 +18,29 @@ module Jekyll arg_is_present? args, "--url", "The 'url' setting can only be set in your config files." end - def self.no_subcommand(args) + def no_subcommand(args) if args.size > 0 && args.first =~ /^--/ && !%w[--help --version].include?(args.first) deprecation_message "Jekyll now uses subcommands instead of just \ switches. Run `jekyll --help' to find out more." end end - def self.arg_is_present?(args, deprecated_argument, message) + def arg_is_present?(args, deprecated_argument, message) if args.include?(deprecated_argument) deprecation_message(message) end end - def self.deprecation_message(message) + def deprecation_message(message) Jekyll.logger.error "Deprecation:", message end - def self.gracefully_require(gem_name) + def defaults_deprecate_type(old, current) + Jekyll.logger.warn "Defaults:", "The '#{old}' type has become '#{current}'." + Jekyll.logger.warn "Defaults:", "Please update your front-matter defaults to use 'type: #{current}'." + end + + def gracefully_require(gem_name) Array(gem_name).each do |name| begin require name diff --git a/lib/jekyll/frontmatter_defaults.rb b/lib/jekyll/frontmatter_defaults.rb index 19472106..bcfc969d 100644 --- a/lib/jekyll/frontmatter_defaults.rb +++ b/lib/jekyll/frontmatter_defaults.rb @@ -10,6 +10,21 @@ module Jekyll @site = site end + def update_deprecated_types(scope) + if scope['type'].eql?('page') + defaults_deprecate_type('page', 'pages') + scope['type'] = 'pages' + elsif scope['type'].eql?('post') + defaults_deprecate_type('post', 'posts') + type.to_s.eql?('posts') + scope['type'] = 'posts' + elsif scope['type'].eql?('draft') + defaults_deprecate_type('draft', 'drafts') + scope['type'] = 'drafts' + end + scope + end + # Finds a default value for a given setting, filtered by path and type # # path - the path (relative to the source) of the page, post or :draft the default is used in @@ -73,8 +88,19 @@ module Jekyll end end + # Determines whether the scope applies to type. + # The scope applies to the type if: + # 1. no 'type' is specified + # 2. the 'type' in the scope is the same as the type asked about + # + # scope - the Hash defaults set being asked about application + # type - the type of the document being processed / asked about + # its defaults. + # + # Returns true if either of the above conditions are satisfied, + # otherwise returns false def applies_type?(scope, type) - !scope.key?('type') || scope['type'] == type.to_s + !scope.key('type') || scope['type'].eql?(type.to_s) end # Checks if a given set of default values is valid @@ -126,12 +152,15 @@ module Jekyll sets = @site.config['defaults'] return [] unless sets.is_a?(Array) - sets.select do |set| - unless valid?(set) - Jekyll.logger.warn "Default:", "An invalid default set was found" + sets.map do |set| + if valid?(set) + update_deprecated_types(set) + else + Jekyll.logger.warn "Defaults:", "An invalid front-matter default set was found:" + Jekyll.logger.warn "#{set}" + nil end - valid?(set) - end + end.compact end # Sanitizes the given path by removing a leading and addding a trailing slash diff --git a/site/_docs/configuration.md b/site/_docs/configuration.md index cbee3ea6..f9b29cdd 100644 --- a/site/_docs/configuration.md +++ b/site/_docs/configuration.md @@ -304,13 +304,13 @@ defaults: - scope: path: "" # an empty string here means all files in the project - type: "post" + type: "posts" values: layout: "default" {% endhighlight %} -Now, this will only set the layout for files where the type is `post`. -The different types that are available to you are `page`, `post`, `draft` or any collection in your site. While `type` is optional, you must specify a value for `path` when creating a `scope/values` pair. +Now, this will only set the layout for files where the type is `posts`. +The different types that are available to you are `pages`, `posts`, `drafts` or any collection in your site. While `type` is optional, you must specify a value for `path` when creating a `scope/values` pair. As mentioned earlier, you can set multiple scope/values pairs for `defaults`. @@ -319,17 +319,16 @@ defaults: - scope: path: "" - type: "post" + type: "posts" values: layout: "my-site" - scope: path: "projects" - type: "page" + type: "pages" values: layout: "project" # overrides previous default layout author: "Mr. Hyde" - category: "project" {% endhighlight %} With these defaults, all posts would use the `my-site` layout. Any html files that exist in the `projects/` folder will use the `project` layout, if it exists. Those files will also have the `page.author` [liquid variable](../variables/) set to `Mr. Hyde` as well as have the category for the page set to `project`. @@ -343,7 +342,7 @@ defaults: - scope: path: "" - type: "my_collection" # a collection in your site + type: "my_collection" # a collection in your site, in plural form values: layout: "default" {% endhighlight %} @@ -365,7 +364,7 @@ defaults: - scope: path: "projects" - type: "page" + type: "pages" values: layout: "project" author: "Mr. Hyde" From 9c090c862f96faf228c9bd839b2e91a68398168e Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Tue, 12 Aug 2014 11:52:16 -0400 Subject: [PATCH 2/5] Ask about 'Draft' before asking about 'Post' `Draft`s are a subclass of `Post` so `draft.is_a?(Post)` will return `true`, thus making all `Draft`s `Post`s, which is not desired. If asking about `Draft` first, then we avoid this problem. Fixes #2726 --- lib/jekyll/convertible.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/jekyll/convertible.rb b/lib/jekyll/convertible.rb index 68cb2b2a..8c8a14d0 100644 --- a/lib/jekyll/convertible.rb +++ b/lib/jekyll/convertible.rb @@ -128,12 +128,12 @@ module Jekyll # # Returns the type of self. def type - if is_a?(Post) + if is_a?(Draft) + :drafts + elsif is_a?(Post) :posts elsif is_a?(Page) :pages - elsif is_a?(Draft) - :drafts end end From e36d433100a2c4fce38c55cce31ddd4e01c5a9a3 Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Tue, 12 Aug 2014 12:22:39 -0400 Subject: [PATCH 3/5] FrontmatterDefaults#update_deprecated_types deals with a set, not a scope --- lib/jekyll/frontmatter_defaults.rb | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/lib/jekyll/frontmatter_defaults.rb b/lib/jekyll/frontmatter_defaults.rb index bcfc969d..3f8e7699 100644 --- a/lib/jekyll/frontmatter_defaults.rb +++ b/lib/jekyll/frontmatter_defaults.rb @@ -10,19 +10,24 @@ module Jekyll @site = site end - def update_deprecated_types(scope) - if scope['type'].eql?('page') - defaults_deprecate_type('page', 'pages') - scope['type'] = 'pages' - elsif scope['type'].eql?('post') - defaults_deprecate_type('post', 'posts') - type.to_s.eql?('posts') - scope['type'] = 'posts' - elsif scope['type'].eql?('draft') - defaults_deprecate_type('draft', 'drafts') - scope['type'] = 'drafts' + def update_deprecated_types(set) + return set unless set.key?('scope') && set['scope'].key?('type') + + set['scope']['type'] = case set['scope']['type'] + when 'page' + Deprecator.defaults_deprecate_type('page', 'pages') + 'pages' + when 'post' + Deprecator.defaults_deprecate_type('post', 'posts') + 'posts' + when 'draft' + Deprecator.defaults_deprecate_type('draft', 'drafts') + 'drafts' + else + set['scope']['type'] end - scope + + set end # Finds a default value for a given setting, filtered by path and type From 2fd155615f0cdfe659272aa609eac399238eb63f Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Tue, 12 Aug 2014 12:22:48 -0400 Subject: [PATCH 4/5] Forgot a question mark == broken tests. --- lib/jekyll/frontmatter_defaults.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jekyll/frontmatter_defaults.rb b/lib/jekyll/frontmatter_defaults.rb index 3f8e7699..8355fa95 100644 --- a/lib/jekyll/frontmatter_defaults.rb +++ b/lib/jekyll/frontmatter_defaults.rb @@ -105,7 +105,7 @@ module Jekyll # Returns true if either of the above conditions are satisfied, # otherwise returns false def applies_type?(scope, type) - !scope.key('type') || scope['type'].eql?(type.to_s) + !scope.key?('type') || scope['type'].eql?(type.to_s) end # Checks if a given set of default values is valid From 90ec93373bc369ddb4d3ef6168301967e2951cd9 Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Tue, 12 Aug 2014 12:24:28 -0400 Subject: [PATCH 5/5] Ensure the new type works. --- test/test_front_matter_defaults.rb | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/test/test_front_matter_defaults.rb b/test/test_front_matter_defaults.rb index fe0244c8..2c793095 100644 --- a/test/test_front_matter_defaults.rb +++ b/test/test_front_matter_defaults.rb @@ -53,7 +53,7 @@ class TestFrontMatterDefaults < Test::Unit::TestCase end end - context "A site with front matter defaults with no path" do + context "A site with front matter defaults with no path and a deprecated type" do setup do @site = Site.new(Jekyll.configuration({ "source" => source_dir, @@ -78,6 +78,31 @@ class TestFrontMatterDefaults < Test::Unit::TestCase end end + context "A site with front matter defaults with no path" do + setup do + @site = Site.new(Jekyll.configuration({ + "source" => source_dir, + "destination" => dest_dir, + "defaults" => [{ + "scope" => { + "type" => "pages" + }, + "values" => { + "key" => "val" + } + }] + })) + @site.process + @affected = @site.pages + @not_affected = @site.posts + end + + should "affect only the specified type and all paths" do + assert_equal @affected.reject { |page| page.data["key"] == "val" }, [] + assert_equal @not_affected.reject { |page| page.data["key"] == "val" }, @not_affected + end + end + context "A site with front matter defaults with no path or type" do setup do @site = Site.new(Jekyll.configuration({