From 604fb3286c9e9625912e45d31b07e18fc79f56aa Mon Sep 17 00:00:00 2001 From: Rodrigo Dumont Date: Sun, 11 May 2014 19:34:51 -0300 Subject: [PATCH] Allow subdirectories in _data --- features/data.feature | 12 ++++++++++++ lib/jekyll/site.rb | 26 ++++++++++++++++++++----- test/source/_data/categories/dairy.yaml | 6 ++++++ test/test_site.rb | 10 ++++++++++ 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 test/source/_data/categories/dairy.yaml diff --git a/features/data.feature b/features/data.feature index 45f5554e..4584f347 100644 --- a/features/data.feature +++ b/features/data.feature @@ -60,6 +60,18 @@ Feature: Data And I should see "Jack" in "_site/index.html" And I should see "Leon" in "_site/index.html" + Scenario: autoload *.yaml files in subdirectories in _data directory + Given I have a _data directory + And I have a _data/categories directory + And I have a "_data/categories/dairy.yaml" file with content: + """ + name: Dairy Products + """ + And I have an "index.html" page that contains "{{ site.data.categories.dairy.name }}" + When I run jekyll build + Then the "_site/index.html" file should exist + And I should see "Dairy Products" in "_site/index.html" + Scenario: should be backward compatible with site.data in _config.yml Given I have a "_config.yml" file with content: """ diff --git a/lib/jekyll/site.rb b/lib/jekyll/site.rb index 5f1580bb..1220879d 100644 --- a/lib/jekyll/site.rb +++ b/lib/jekyll/site.rb @@ -196,17 +196,33 @@ module Jekyll # Returns nothing def read_data(dir) base = File.join(source, dir) - return unless File.directory?(base) && (!safe || !File.symlink?(base)) + read_data_to(base, self.data) + end - entries = Dir.chdir(base) { Dir['*.{yaml,yml,json}'] } - entries.delete_if { |e| File.directory?(File.join(base, e)) } + # Read and parse all yaml files under and add them to the + # variable. + # + # dir - The string absolute path of the directory to read. + # data - The variable to which data will be added. + # + # Returns nothing + def read_data_to(dir, data) + return unless File.directory?(dir) && (!safe || !File.symlink?(dir)) + + entries = Dir.chdir(dir) do + Dir['*.{yaml,yml,json}'] + Dir['*'].select { |fn| File.directory?(fn) } + end entries.each do |entry| - path = File.join(source, dir, entry) + path = File.join(dir, entry) next if File.symlink?(path) && safe key = sanitize_filename(File.basename(entry, '.*')) - self.data[key] = SafeYAML.load_file(path) + if File.directory?(path) + read_data_to(path, data[key] = {}) + else + data[key] = SafeYAML.load_file(path) + end end end diff --git a/test/source/_data/categories/dairy.yaml b/test/source/_data/categories/dairy.yaml new file mode 100644 index 00000000..c091a68c --- /dev/null +++ b/test/source/_data/categories/dairy.yaml @@ -0,0 +1,6 @@ +name: Dairy +products: +- name: cheese + price: 5.3 +- name: milk + price: 2.5 \ No newline at end of file diff --git a/test/test_site.rb b/test/test_site.rb index 94263491..1163a61a 100644 --- a/test/test_site.rb +++ b/test/test_site.rb @@ -388,6 +388,16 @@ class TestSite < Test::Unit::TestCase assert_equal site.site_payload['site']['data']['members'], file_content end + should 'auto load yaml files in subdirectory' do + site = Site.new(Jekyll.configuration) + site.process + + file_content = SafeYAML.load_file(File.join(source_dir, '_data', 'categories', 'dairy.yaml')) + + assert_equal site.data['categories']['dairy'], file_content + assert_equal site.site_payload['site']['data']['categories']['dairy'], file_content + end + should "load symlink files in unsafe mode" do site = Site.new(Jekyll.configuration.merge({'safe' => false})) site.process