Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support a new relative_include tag #2870

Merged
merged 10 commits into from
Sep 7, 2014
26 changes: 20 additions & 6 deletions lib/jekyll/tags/include.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ class IncludeTag < Liquid::Tag
VALID_SYNTAX = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/
VARIABLE_SYNTAX = /(?<variable>[^{]*\{\{\s*(?<name>[\w\-\.]+)\s*(\|.*)?\}\}[^\s}]*)(?<params>.*)/

INCLUDES_DIR = '_includes'

def initialize(tag_name, markup, tokens)
@tag_name = tag_name
case tag_name
when 'include'
@includes_dir = '_includes'
when 'relative_include'
@includes_dir = ''
end

super
matched = markup.strip.match(VARIABLE_SYNTAX)
if matched
Expand Down Expand Up @@ -97,8 +103,12 @@ def render_variable(context)
end

def render(context)
dir = File.join(File.realpath(context.registers[:site].source), INCLUDES_DIR)

case @tag_name
when 'include'
dir = File.join(File.realpath(context.registers[:site].source), @includes_dir)
when 'relative_include'
dir = File.join(File.realpath(context.registers[:site].source), File.dirname(context.registers[:page]["path"]))
end
file = render_variable(context) || @file
validate_file_name(file)

Expand All @@ -113,7 +123,7 @@ def render(context)
partial.render!(context)
end
rescue => e
raise IncludeTagError.new e.message, File.join(INCLUDES_DIR, @file)
raise IncludeTagError.new e.message, File.join(@includes_dir, @file)
end
end

Expand All @@ -126,7 +136,7 @@ def validate_path(path, dir, safe)
end

def path_relative_to_source(dir, path)
File.join(INCLUDES_DIR, path.sub(Regexp.new("^#{dir}"), ""))
File.join(@includes_dir, path.sub(Regexp.new("^#{dir}"), ""))
end

def realpath_prefixed_with?(path, dir)
Expand All @@ -138,7 +148,11 @@ def source(file, context)
File.read(file, file_read_opts(context))
end
end

class RelativeIncludeTag < IncludeTag
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use case statements instead of just overwrite certain methods based on the tag class? If you have a separate class, you may as well separate the class-specific code from each other. 😉

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true.dat

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want me to do that, I am happy to submit a PR to your PR. Or something? #howtogithub

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I was planing on just killing this and relying more on tag_name to do the weight. There's only two spots that need to change. Does that make sense? #howdoiprogram

end
end

Liquid::Template.register_tag('include', Jekyll::Tags::IncludeTag)
Liquid::Template.register_tag('relative_include', Jekyll::Tags::RelativeIncludeTag)
25 changes: 25 additions & 0 deletions test/source/_posts/2014-09-02-relative-includes.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
title: Post
layout: post
include1: rel_include.html
include2: relative_includes/rel_include
include3: rel_INCLUDE
include4: params
include5: clude
---

Liquid tests
- 1 {% relative_include relative_includes/{{ page.include1 }} %}
- 2 {% relative_include {{ page.include2 | append: '.html' }} %}
- 3 {% relative_include relative_includes/{{ page.include3 | downcase | append: '.html' }} %}

Whitespace tests
- 4 {% relative_include relative_includes/{{page.include1}} %}
- 5 {% relative_include relative_includes/{{ page.include1}} %}
- 6 {% relative_include relative_includes/{{ page.include3 | downcase | append: '.html'}} %}

Parameters test
- 7 {% relative_include relative_includes/{{ page.include4 | append: '.html' }} var1='foo' var2='bar' %}

Partial variable test
- 8 {% relative_include relative_includes/rel_in{{ page.include5 }}.html %}
7 changes: 7 additions & 0 deletions test/source/_posts/relative_includes/params.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<span id='include-param'>{{include.param}}</span>

<ul id='param-list'>
{% for param in include %}
<li>{{param[0]}} = {{param[1]}}</li>
{% endfor %}
</ul>
1 change: 1 addition & 0 deletions test/source/_posts/relative_includes/rel_include.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
relative_included
2 changes: 1 addition & 1 deletion test/test_generated_site.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class TestGeneratedSite < Test::Unit::TestCase
end

should "ensure post count is as expected" do
assert_equal 42, @site.posts.size
assert_equal 43, @site.posts.size
end

should "insert site.posts into the index" do
Expand Down
2 changes: 1 addition & 1 deletion test/test_site.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class TestSite < Test::Unit::TestCase
Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir})
end
@site = Site.new(Jekyll.configuration)
@num_invalid_posts = 2
@num_invalid_posts = 4
end

should "have an empty tag hash by default" do
Expand Down
35 changes: 35 additions & 0 deletions test/test_tags.rb
Original file line number Diff line number Diff line change
Expand Up @@ -509,5 +509,40 @@ def fill_post(code, override = {})
assert_match %r{8 included}, @content
end
end

context "relative include tag with variable and liquid filters" do
setup do
stub(Jekyll).configuration do
site_configuration({'pygments' => true})
end

site = Site.new(Jekyll.configuration)
post = Post.new(site, source_dir, '', "2014-09-02-relative-includes.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 relative_include}, @content
assert_match %r{2 relative_include}, @content
assert_match %r{3 relative_include}, @content
end

should "include file as variable and liquid filters with arbitrary whitespace" do
assert_match %r{4 relative_include}, @content
assert_match %r{5 relative_include}, @content
assert_match %r{6 relative_include}, @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

should "include file as partial variable" do
assert_match %r{8 relative_include}, @content
end
end
end
end