diff --git a/features/include_tag.feature b/features/include_tag.feature
index 587784dc..5f0e5799 100644
--- a/features/include_tag.feature
+++ b/features/include_tag.feature
@@ -55,3 +55,14 @@ Feature: Include tags
When I run jekyll
Then the _site directory should exist
And I should see "one two" in "_site/index.html"
+
+ Scenario: Include a file with variables and filters
+ Given I have an _includes directory
+ And I have an "_includes/one.html" file that contains "one included"
+ And I have a configuration file with:
+ | key | value |
+ | include_file | one |
+ And I have an "index.html" page that contains "{% include {{ site.include_file | append: '.html' }} %}"
+ When I run jekyll
+ Then the _site directory should exist
+ And I should see "one included" in "_site/index.html"
diff --git a/lib/jekyll/tags/include.rb b/lib/jekyll/tags/include.rb
index 49033ab0..5c679dc1 100644
--- a/lib/jekyll/tags/include.rb
+++ b/lib/jekyll/tags/include.rb
@@ -14,12 +14,19 @@ module Jekyll
SYNTAX_EXAMPLE = "{% include file.ext param='value' param2='value' %}"
VALID_SYNTAX = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/
+ VARIABLE_SYNTAX = /(?\{\{\s*(?[\w\-\.]+)\s*(\|.*)?\}\})(?.*)/
INCLUDES_DIR = '_includes'
def initialize(tag_name, markup, tokens)
super
- @file, @params = markup.strip.split(' ', 2);
+ matched = markup.strip.match(VARIABLE_SYNTAX)
+ if matched
+ @file = matched['variable'].strip
+ @params = matched['params'].strip
+ else
+ @file, @params = markup.strip.split(' ', 2);
+ end
validate_params if @params
end
@@ -48,7 +55,7 @@ module Jekyll
raise ArgumentError.new <<-eos
Invalid syntax for include tag. File contains invalid characters or sequences:
- #{@file}
+ #{file}
Valid syntax:
@@ -79,10 +86,11 @@ eos
context.registers[:site].file_read_opts
end
- def retrieve_variable(context)
- if /\{\{([\w\-\.]+)\}\}/ =~ @file
- raise ArgumentError.new("No variable #{$1} was found in include tag") if context[$1].nil?
- context[$1]
+ # Render the variable if required
+ def render_variable(context)
+ if @file.match(VARIABLE_SYNTAX)
+ partial = Liquid::Template.parse(@file)
+ partial.render!(context)
end
end
@@ -90,7 +98,7 @@ eos
dir = File.join(context.registers[:site].source, INCLUDES_DIR)
validate_dir(dir, context.registers[:site].safe)
- file = retrieve_variable(context) || @file
+ file = render_variable(context) || @file
validate_file_name(file)
path = File.join(dir, file)
@@ -116,9 +124,9 @@ eos
def validate_file(file, safe)
if !File.exists?(file)
- raise IOError.new "Included file '#{@file}' not found in '#{INCLUDES_DIR}' directory"
+ raise IOError.new "Included file '#{file}' not found"
elsif File.symlink?(file) && safe
- raise IOError.new "The included file '#{INCLUDES_DIR}/#{@file}' should not be a symlink"
+ raise IOError.new "The included file '#{file}' should not be a symlink"
end
end
diff --git a/site/docs/templates.md b/site/docs/templates.md
index 7cf2a865..67b30123 100644
--- a/site/docs/templates.md
+++ b/site/docs/templates.md
@@ -209,9 +209,7 @@ root of your source directory. This will embed the contents of
The name of the file you wish to embed can be literal (as in the example above),
or you can use a variable, using liquid-like variable syntax as in
- {% raw %}{% include {{my_variable}} %}{% endraw %}
.
-
- Note that unlike usual liquid variable syntax, you cannot have spaces inside the curly braces.
+ {% raw %}{% include {{ my_variable }} %}{% endraw %}
.
diff --git a/test/source/_includes/include.html b/test/source/_includes/include.html
new file mode 100644
index 00000000..201a102c
--- /dev/null
+++ b/test/source/_includes/include.html
@@ -0,0 +1 @@
+included
diff --git a/test/source/_posts/2013-12-17-include-variable-filters.markdown b/test/source/_posts/2013-12-17-include-variable-filters.markdown
new file mode 100644
index 00000000..3d66e879
--- /dev/null
+++ b/test/source/_posts/2013-12-17-include-variable-filters.markdown
@@ -0,0 +1,21 @@
+---
+title: Post
+layout: post
+include1: include.html
+include2: include
+include3: INCLUDE
+include4: params
+---
+
+Liquid tests
+- 1 {% include {{ page.include1 }} %}
+- 2 {% include {{ page.include2 | append: '.html' }} %}
+- 3 {% include {{ page.include3 | downcase | append: '.html' }} %}
+
+Whitespace tests
+- 4 {% include {{page.include1}} %}
+- 5 {% include {{ page.include1}} %}
+- 6 {% include {{ page.include3 | downcase | append: '.html'}} %}
+
+Parameters test
+- 7 {% include {{ page.include4 | append: '.html' }} var1='foo' var2='bar' %}
diff --git a/test/test_generated_site.rb b/test/test_generated_site.rb
index 801675bf..866f753c 100644
--- a/test/test_generated_site.rb
+++ b/test/test_generated_site.rb
@@ -14,7 +14,7 @@ class TestGeneratedSite < Test::Unit::TestCase
end
should "ensure post count is as expected" do
- assert_equal 36, @site.posts.size
+ assert_equal 37, @site.posts.size
end
should "insert site.posts into the index" do
diff --git a/test/test_tags.rb b/test/test_tags.rb
index b21f4931..926c7f18 100644
--- a/test/test_tags.rb
+++ b/test/test_tags.rb
@@ -471,5 +471,35 @@ CONTENT
end
end
+ context "include tag with variable and liquid filters" do
+ setup do
+ stub(Jekyll).configuration do
+ Jekyll::Configuration::DEFAULTS.deep_merge({'pygments' => true}).deep_merge({'source' => source_dir, 'destination' => dest_dir})
+ end
+
+ site = Site.new(Jekyll.configuration)
+ post = Post.new(site, source_dir, '', "2013-12-17-include-variable-filters.markdown")
+ layouts = { "default" => Layout.new(site, source_dir('_layouts'), "simple.html")}
+ post.render(layouts, {"site" => {"posts" => []}})
+ @content = post.content
+ end
+
+ should "include file as variable with liquid filters" do
+ assert_match %r{1 included}, @content
+ assert_match %r{2 included}, @content
+ assert_match %r{3 included}, @content
+ end
+
+ should "include file as variable and liquid filters with arbitrary whitespace" do
+ assert_match %r{4 included}, @content
+ assert_match %r{5 included}, @content
+ assert_match %r{6 included}, @content
+ end
+
+ should "include file as variable and filters with additional parameters" do
+ assert_match 'var1 = foo', @content
+ assert_match 'var2 = bar', @content
+ end
+ end
end
end