diff --git a/lib/liquid/tags/include.rb b/lib/liquid/tags/include.rb index bbcfb1c..d90c731 100644 --- a/lib/liquid/tags/include.rb +++ b/lib/liquid/tags/include.rb @@ -16,18 +16,20 @@ module Liquid # {% include 'product' for products %} # class Include < Tag - Syntax = /(#{QuotedFragment}+)(\s+(?:with|for)\s+(#{QuotedFragment}+))?/o + SYNTAX = /(#{QuotedFragment}+)(\s+(?:with|for)\s+(#{QuotedFragment}+))?(\s+(?:as)\s+(#{VariableSegment}+))?/o + Syntax = SYNTAX attr_reader :template_name_expr, :variable_name_expr, :attributes def initialize(tag_name, markup, options) super - if markup =~ Syntax + if markup =~ SYNTAX template_name = Regexp.last_match(1) variable_name = Regexp.last_match(3) + @alias_name = Regexp.last_match(5) @variable_name_expr = variable_name ? Expression.parse(variable_name) : nil @template_name_expr = Expression.parse(template_name) @attributes = {} @@ -54,7 +56,7 @@ module Liquid parse_context: parse_context ) - context_variable_name = template_name.split('/').last + context_variable_name = @alias_name || template_name.split('/').last variable = if @variable_name_expr context.evaluate(@variable_name_expr) diff --git a/lib/liquid/tags/render.rb b/lib/liquid/tags/render.rb index 1403b58..c322247 100644 --- a/lib/liquid/tags/render.rb +++ b/lib/liquid/tags/render.rb @@ -2,7 +2,7 @@ module Liquid class Render < Tag - SYNTAX = /(#{QuotedString})#{QuotedFragment}*/o + SYNTAX = /(#{QuotedString}+)(\s+(?:with|for)\s+(#{QuotedFragment}+))?(\s+(?:as)\s+(#{VariableSegment}+))?/o disable_tags "include" @@ -14,7 +14,10 @@ module Liquid raise SyntaxError, options[:locale].t("errors.syntax.render") unless markup =~ SYNTAX template_name = Regexp.last_match(1) + variable_name = Regexp.last_match(3) + @alias_name = Regexp.last_match(5) + @variable_name_expr = variable_name ? Expression.parse(variable_name) : nil @template_name_expr = Expression.parse(template_name) @attributes = {} @@ -38,13 +41,21 @@ module Liquid parse_context: parse_context ) - inner_context = context.new_isolated_subcontext - inner_context.template_name = template_name - inner_context.partial = true - @attributes.each do |key, value| - inner_context[key] = context.evaluate(value) - end - partial.render_to_output_buffer(inner_context, output) + context_variable_name = @alias_name || template_name.split('/').last + + render_partial_func = ->(var) { + inner_context = context.new_isolated_subcontext + inner_context.template_name = template_name + inner_context.partial = true + @attributes.each do |key, value| + inner_context[key] = context.evaluate(value) + end + inner_context[context_variable_name] = var unless var.nil? + partial.render_to_output_buffer(inner_context, output) + } + + variable = @variable_name_expr ? context.evaluate(@variable_name_expr) : nil + variable.is_a?(Array) ? variable.each(&render_partial_func) : render_partial_func.call(variable) output end diff --git a/test/integration/tags/include_tag_test.rb b/test/integration/tags/include_tag_test.rb index 1a20e36..c0400a0 100644 --- a/test/integration/tags/include_tag_test.rb +++ b/test/integration/tags/include_tag_test.rb @@ -8,6 +8,9 @@ class TestFileSystem when "product" "Product: {{ product.title }} " + when "product_alias" + "Product: {{ product.title }} " + when "locale_variables" "Locale: {{echo1}} {{echo2}}" @@ -91,6 +94,16 @@ class IncludeTagTest < Minitest::Test "{% include 'product' with products[0] %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }]) end + def test_include_tag_with_alias + assert_template_result("Product: Draft 151cm ", + "{% include 'product_alias' with products[0] as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }]) + end + + def test_include_tag_for_alias + assert_template_result("Product: Draft 151cm Product: Element 155cm ", + "{% include 'product_alias' for products as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }]) + end + def test_include_tag_with_default_name assert_template_result("Product: Draft 151cm ", "{% include 'product' %}", "product" => { 'title' => 'Draft 151cm' }) diff --git a/test/integration/tags/render_tag_test.rb b/test/integration/tags/render_tag_test.rb index 151aa9e..f2fbc55 100644 --- a/test/integration/tags/render_tag_test.rb +++ b/test/integration/tags/render_tag_test.rb @@ -165,4 +165,44 @@ class RenderTagTest < Minitest::Test assert_template_result('include usage is not allowed in this contextinclude usage is not allowed in this context', '{% render "nested_render_with_sibling_include" %}') end + + def test_render_tag_with + Liquid::Template.file_system = StubFileSystem.new( + 'product' => "Product: {{ product.title }} ", + 'product_alias' => "Product: {{ product.title }} ", + ) + + assert_template_result("Product: Draft 151cm ", + "{% render 'product' with products[0] %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }]) + end + + def test_render_tag_with_alias + Liquid::Template.file_system = StubFileSystem.new( + 'product' => "Product: {{ product.title }} ", + 'product_alias' => "Product: {{ product.title }} ", + ) + + assert_template_result("Product: Draft 151cm ", + "{% render 'product_alias' with products[0] as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }]) + end + + def test_render_tag_for_alias + Liquid::Template.file_system = StubFileSystem.new( + 'product' => "Product: {{ product.title }} ", + 'product_alias' => "Product: {{ product.title }} ", + ) + + assert_template_result("Product: Draft 151cm Product: Element 155cm ", + "{% render 'product_alias' for products as product %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }]) + end + + def test_render_tag_for + Liquid::Template.file_system = StubFileSystem.new( + 'product' => "Product: {{ product.title }} ", + 'product_alias' => "Product: {{ product.title }} ", + ) + + assert_template_result("Product: Draft 151cm Product: Element 155cm ", + "{% render 'product' for products %}", "products" => [{ 'title' => 'Draft 151cm' }, { 'title' => 'Element 155cm' }]) + end end