diff --git a/features/data.feature b/features/data.feature
index 45f5554e..4f0e32ed 100644
--- a/features/data.feature
+++ b/features/data.feature
@@ -60,6 +60,35 @@ 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: folders should have precedence over files with the same name
+ 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 a "_data/categories.yaml" file with content:
+ """
+ dairy:
+ name: Should not display this
+ """
+ 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 9efe2500..9b05f0f7 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/site/docs/datafiles.md b/site/docs/datafiles.md
index 05e59345..dbac1dec 100644
--- a/site/docs/datafiles.md
+++ b/site/docs/datafiles.md
@@ -61,3 +61,47 @@ You can now render the list of members in a template:
{% endraw %}
{% endhighlight %}
+
+## Example: Organizations
+
+Data files can also be placed in sub-folders of the `_data` folder. Each folder level will be added to a variable's namespace. The example bellow shows how GitHub organizations could be defined separately in a file under the `orgs` folder:
+
+In `_data/orgs/jekyll.yml`:
+
+{% highlight yaml %}
+username: jekyll
+name: Jekyll
+members:
+ - name: Tom Preston-Werner
+ github: mojombo
+
+ - name: Parker Moore
+ github: parkr
+{% endhighlight %}
+
+In `_data/orgs/doeorg.yml`:
+
+{% highlight yaml %}
+username: doeorg
+name: Doe Org
+members:
+ - name: John Doe
+ github: jdoe
+{% endhighlight %}
+
+The organizations can then be accessed via `site.data.orgs`, followed by the file name:
+
+{% highlight html %}
+{% raw %}
+
+{% for org in site.data.orgs %}
+ -
+
+ {{ org.name }}
+
+ ({{ org.members | size }} members)
+
+{% endfor %}
+
+{% endraw %}
+{% endhighlight %}
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 de02b8dd..48290d45 100644
--- a/test/test_site.rb
+++ b/test/test_site.rb
@@ -389,6 +389,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