Merge pull request #1841 from jens-na/include-variable-liquid-filters

This commit is contained in:
Parker Moore 2013-12-25 22:11:33 -08:00
commit 6e8f31f406
7 changed files with 82 additions and 13 deletions

View File

@ -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"

View File

@ -14,12 +14,19 @@ module Jekyll
SYNTAX_EXAMPLE = "{% include file.ext param='value' param2='value' %}"
VALID_SYNTAX = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/
VARIABLE_SYNTAX = /(?<variable>\{\{\s*(?<name>[\w\-\.]+)\s*(\|.*)?\}\})(?<params>.*)/
INCLUDES_DIR = '_includes'
def initialize(tag_name, markup, tokens)
super
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

View File

@ -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
<code>{% raw %}{% include {{my_variable}} %}{% endraw %}</code>.
Note that unlike usual liquid variable syntax, you cannot have spaces inside the curly braces.
<code>{% raw %}{% include {{ my_variable }} %}{% endraw %}</code>.
</p>
</div>

View File

@ -0,0 +1 @@
included

View File

@ -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' %}

View File

@ -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

View File

@ -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 '<li>var1 = foo</li>', @content
assert_match '<li>var2 = bar</li>', @content
end
end
end
end