From c8786b7b281281bd127309b2a8fafea38c5d2cac Mon Sep 17 00:00:00 2001 From: Jens Nazarenus Date: Fri, 16 May 2014 00:04:31 +0200 Subject: [PATCH 1/6] Adds default front-matter support for collecitons --- lib/jekyll/document.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/jekyll/document.rb b/lib/jekyll/document.rb index 0fb6719f..f4f70e18 100644 --- a/lib/jekyll/document.rb +++ b/lib/jekyll/document.rb @@ -176,6 +176,8 @@ module Jekyll end # Read in the file and assign the content and data based on the file contents. + # Merge the frontmatter of the file with the frontmatter default + # values # # Returns nothing. def read(opts = {}) @@ -183,10 +185,17 @@ module Jekyll @data = SafeYAML.load_file(path) else begin + defaults = @site.frontmatter_defaults.all(path, collection.label.to_sym) + unless defaults.empty? + @data = defaults + end @content = File.read(path, merged_file_read_opts(opts)) if content =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m @content = $POSTMATCH - @data = SafeYAML.load($1) + data_file = SafeYAML.load($1) + unless data_file.nil? + @data = Utils.deep_merge_hashes(defaults, data_file) + end end rescue SyntaxError => e puts "YAML Exception reading #{path}: #{e.message}" From e868a8437f9e0f6b28f6cfa897c524454c3df3ef Mon Sep 17 00:00:00 2001 From: Jens Nazarenus Date: Sat, 17 May 2014 01:21:57 +0200 Subject: [PATCH 2/6] Includes tests for frontmatter defaults in documents --- features/frontmatter_defaults.feature | 51 +++++++++++++++++++++++++++ test/test_document.rb | 39 ++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/features/frontmatter_defaults.feature b/features/frontmatter_defaults.feature index 3f2d3cd5..683af655 100644 --- a/features/frontmatter_defaults.feature +++ b/features/frontmatter_defaults.feature @@ -77,3 +77,54 @@ Feature: frontmatter defaults Then I should see "a blog by some guy" in "_site/frontmatter.html" And I should see "nothing" in "_site/override.html" But the "_site/perma.html" file should not exist + + Scenario: Use frontmatter defaults in collections + Given I have a _slides directory + And I have a "index.html" file that contains "nothing" + And I have a "_slides/slide1.html" file with content: + """ + Value: {{ page.myval }} + """ + And I have a "_config.yml" file with content: + """ + collections: + slides: + output: true + defaults: + - + scope: + path: "" + type: slides + values: + myval: "Test" + """ + When I run jekyll build + Then the _site directory should exist + And I should see "Value: Test" in "_site/slides/slide1.html" + + Scenario: Override frontmatter defaults inside a collection + Given I have a _slides directory + And I have a "index.html" file that contains "nothing" + And I have a "_slides/slide2.html" file with content: + """ + --- + myval: Override + --- + Value: {{ page.myval }} + """ + And I have a "_config.yml" file with content: + """ + collections: + slides: + output: true + defaults: + - + scope: + path: "" + type: slides + values: + myval: "Test" + """ + When I run jekyll build + Then the _site directory should exist + And I should see "Value: Override" in "_site/slides/slide2.html" diff --git a/test/test_document.rb b/test/test_document.rb index 794c2117..ee52a280 100644 --- a/test/test_document.rb +++ b/test/test_document.rb @@ -42,6 +42,45 @@ class TestDocument < Test::Unit::TestCase end + context "a document as part of a collection with frontmatter defaults" do + setup do + @site = Site.new(Jekyll.configuration({ + "collections" => ["methods"], + "source" => source_dir, + "destination" => dest_dir, + "defaults" => [{ + "scope"=> {"path"=>"", "type"=>"methods"}, + "values"=> { + "nested"=> { + "test1"=>"default1", + "test2"=>"default1" + } + } + }] + })) + @site.process + @document = @site.collections["methods"].docs.first + end + + should "know the frontmatter defaults" do + assert_equal({ + "title"=>"Jekyll.configuration", + "nested"=> { + "test1"=>"default1", + "test2"=>"default1"}, + "whatever"=>"foo.bar" + }, @document.data) + end + + should "overwrite a default value in the document frontmatter" do + + end + + should "overwrite a nested default value in the document frontmatter" do + + end + end + context " a document part of a rendered collection" do end From 497c10897f9a767b66aeeab42b2a849034fb594e Mon Sep 17 00:00:00 2001 From: Jens Nazarenus Date: Wed, 21 May 2014 20:24:53 +0200 Subject: [PATCH 3/6] Passes the url to FrontmatterDefaults.all instead of full path --- lib/jekyll/document.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/jekyll/document.rb b/lib/jekyll/document.rb index f4f70e18..74f9aa39 100644 --- a/lib/jekyll/document.rb +++ b/lib/jekyll/document.rb @@ -185,7 +185,7 @@ module Jekyll @data = SafeYAML.load_file(path) else begin - defaults = @site.frontmatter_defaults.all(path, collection.label.to_sym) + defaults = @site.frontmatter_defaults.all(url, collection.label.to_sym) unless defaults.empty? @data = defaults end From ae679405441cf2bf6426486c97f8dc67006a3070 Mon Sep 17 00:00:00 2001 From: Jens Nazarenus Date: Wed, 21 May 2014 20:30:37 +0200 Subject: [PATCH 4/6] Adds the missing tests for #2405 --- test/source/_slides/example-slide-1.html | 4 + test/source/_slides/example-slide-2.html | 7 ++ test/test_document.rb | 102 ++++++++++++++++++++--- 3 files changed, 102 insertions(+), 11 deletions(-) create mode 100644 test/source/_slides/example-slide-1.html create mode 100644 test/source/_slides/example-slide-2.html diff --git a/test/source/_slides/example-slide-1.html b/test/source/_slides/example-slide-1.html new file mode 100644 index 00000000..fcd89b3c --- /dev/null +++ b/test/source/_slides/example-slide-1.html @@ -0,0 +1,4 @@ +--- + title: Example slide + layout: slide +--- diff --git a/test/source/_slides/example-slide-2.html b/test/source/_slides/example-slide-2.html new file mode 100644 index 00000000..15158990 --- /dev/null +++ b/test/source/_slides/example-slide-2.html @@ -0,0 +1,7 @@ +--- + title: Override title + layout: slide + nested: + test1: override1 + test2: override2 +--- diff --git a/test/test_document.rb b/test/test_document.rb index ee52a280..bb2355f0 100644 --- a/test/test_document.rb +++ b/test/test_document.rb @@ -45,11 +45,41 @@ class TestDocument < Test::Unit::TestCase context "a document as part of a collection with frontmatter defaults" do setup do @site = Site.new(Jekyll.configuration({ - "collections" => ["methods"], + "collections" => ["slides"], "source" => source_dir, "destination" => dest_dir, "defaults" => [{ - "scope"=> {"path"=>"", "type"=>"methods"}, + "scope"=> {"path"=>"", "type"=>"slides"}, + "values"=> { + "nested"=> { + "key"=>"myval", + } + } + }] + })) + @site.process + @document = @site.collections["slides"].docs.first + end + + should "know the frontmatter defaults" do + assert_equal({ + "title"=>"Example slide", + "layout"=>"slide", + "nested"=> { + "key"=>"myval" + } + }, @document.data) + end + end + + context "a document as part of a collection with overriden default values" do + setup do + @site = Site.new(Jekyll.configuration({ + "collections" => ["slides"], + "source" => source_dir, + "destination" => dest_dir, + "defaults" => [{ + "scope"=> {"path"=>"", "type"=>"slides"}, "values"=> { "nested"=> { "test1"=>"default1", @@ -59,25 +89,75 @@ class TestDocument < Test::Unit::TestCase }] })) @site.process - @document = @site.collections["methods"].docs.first + @document = @site.collections["slides"].docs[1] + end + + should "override default values in the document frontmatter" do + assert_equal({ + "title"=>"Override title", + "layout"=>"slide", + "nested"=> { + "test1"=>"override1", + "test2"=>"override2" + } + }, @document.data) + end + end + + context "a document as part of a collection with valid path" do + setup do + @site = Site.new(Jekyll.configuration({ + "collections" => ["slides"], + "source" => source_dir, + "destination" => dest_dir, + "defaults" => [{ + "scope"=> {"path"=>"slides", "type"=>"slides"}, + "values"=> { + "nested"=> { + "key"=>"value123", + } + } + }] + })) + @site.process + @document = @site.collections["slides"].docs.first end should "know the frontmatter defaults" do assert_equal({ - "title"=>"Jekyll.configuration", + "title"=>"Example slide", + "layout"=>"slide", "nested"=> { - "test1"=>"default1", - "test2"=>"default1"}, - "whatever"=>"foo.bar" + "key"=>"value123" + } }, @document.data) end + end - should "overwrite a default value in the document frontmatter" do - + context "a document as part of a collection with invalid path" do + setup do + @site = Site.new(Jekyll.configuration({ + "collections" => ["slides"], + "source" => source_dir, + "destination" => dest_dir, + "defaults" => [{ + "scope"=> {"path"=>"somepath", "type"=>"slides"}, + "values"=> { + "nested"=> { + "key"=>"myval", + } + } + }] + })) + @site.process + @document = @site.collections["slides"].docs.first end - should "overwrite a nested default value in the document frontmatter" do - + should "not know the specified frontmatter defaults" do + assert_equal({ + "title"=>"Example slide", + "layout"=>"slide" + }, @document.data) end end From 460d9c1c443c81ffac95c7d5a496506feded33fe Mon Sep 17 00:00:00 2001 From: Jens Nazarenus Date: Sun, 1 Jun 2014 21:53:21 +0200 Subject: [PATCH 5/6] Adds an example how to use frontmatter defaults with collections --- site/docs/configuration.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/site/docs/configuration.md b/site/docs/configuration.md index e9a21db7..23b16e9a 100644 --- a/site/docs/configuration.md +++ b/site/docs/configuration.md @@ -309,7 +309,8 @@ defaults: 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`, or `draft`. 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 `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. As mentioned earlier, you can set multiple scope/values pairs for `defaults`. @@ -333,6 +334,22 @@ defaults: 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`. +{% highlight yaml %} +collections: + - my_collection: + output: true + +defaults: + - + scope: + path: "" + type: "my_collection" # a collection in your site + values: + layout: "default" +{% endhighlight %} + +In this example the `layout` is set to `default` inside the [collection](../collections) with the name `my_collection`. + ### Precedence Jekyll will apply all of the configuration settings you specify in the `defaults` section of your `_config.yml` file. However, you can choose to override settings from other scope/values pair by specifying a more specific path for the scope. From 467945bedbe5928f75742b933012db2e4e5d2cc2 Mon Sep 17 00:00:00 2001 From: Jens Nazarenus Date: Sun, 1 Jun 2014 21:00:27 +0200 Subject: [PATCH 6/6] Fixes the extra indentation in cucumber test --- features/frontmatter_defaults.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/frontmatter_defaults.feature b/features/frontmatter_defaults.feature index 683af655..c3e7c8de 100644 --- a/features/frontmatter_defaults.feature +++ b/features/frontmatter_defaults.feature @@ -108,7 +108,7 @@ Feature: frontmatter defaults And I have a "_slides/slide2.html" file with content: """ --- - myval: Override + myval: Override --- Value: {{ page.myval }} """