mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-13 16:00:41 -07:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47fbff07fa |
@@ -64,6 +64,7 @@ require 'liquid/strainer_template'
|
||||
require 'liquid/expression'
|
||||
require 'liquid/context'
|
||||
require 'liquid/parser_switching'
|
||||
require 'liquid/renderabledrop'
|
||||
require 'liquid/tag'
|
||||
require 'liquid/tag/disabler'
|
||||
require 'liquid/tag/disableable'
|
||||
|
||||
@@ -24,5 +24,6 @@
|
||||
render: "Syntax error in tag 'render' - Template name must be a quoted string"
|
||||
argument:
|
||||
include: "Argument error in tag 'include' - Illegal template name"
|
||||
render: "Argument error in tag 'render' - Illegal template name"
|
||||
disabled:
|
||||
tag: "usage is not allowed in this context"
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Liquid
|
||||
class RenderableDrop < Drop
|
||||
def render(_context, _output)
|
||||
raise NotImplementedError, "render must be implemented for #{self.class.name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3,7 +3,20 @@
|
||||
module Liquid
|
||||
class Render < Tag
|
||||
FOR = 'for'
|
||||
SYNTAX = /(#{QuotedString}+)(\s+(with|#{FOR})\s+(#{QuotedFragment}+))?(\s+(?:as)\s+(#{VariableSegment}+))?/o
|
||||
SYNTAX = %r{
|
||||
(
|
||||
## for {% render "snippet" %}
|
||||
#{Liquid::QuotedString}+ |
|
||||
## for {% render block %}
|
||||
\A#{Liquid::VariableSegment}+
|
||||
)
|
||||
## for {% render "snippet" with product as p %}
|
||||
## or {% render "snippet" for products p %}
|
||||
(\s+(with|#{Liquid::Render::FOR})\s+(#{Liquid::QuotedFragment}+))?
|
||||
(\s+(?:as)\s+(#{Liquid::VariableSegment}+))?
|
||||
## variables passed into the tag (e.g. {% render "snippet", var1: value1, var2: value2 %}
|
||||
## are not matched by this regex and are handled by .initialize
|
||||
}xo
|
||||
|
||||
disable_tags "include"
|
||||
|
||||
@@ -14,13 +27,13 @@ module Liquid
|
||||
|
||||
raise SyntaxError, options[:locale].t("errors.syntax.render") unless markup =~ SYNTAX
|
||||
|
||||
template_name = Regexp.last_match(1)
|
||||
@template_name = Regexp.last_match(1)
|
||||
with_or_for = Regexp.last_match(3)
|
||||
variable_name = Regexp.last_match(4)
|
||||
|
||||
@alias_name = Regexp.last_match(6)
|
||||
@variable_name_expr = variable_name ? parse_expression(variable_name) : nil
|
||||
@template_name_expr = parse_expression(template_name)
|
||||
@template_name_expr = parse_expression(@template_name)
|
||||
@for = (with_or_for == FOR)
|
||||
|
||||
@attributes = {}
|
||||
@@ -34,9 +47,21 @@ module Liquid
|
||||
end
|
||||
|
||||
def render_tag(context, output)
|
||||
# Though we evaluate this here we will only ever parse it as a string literal.
|
||||
template_name = context.evaluate(@template_name_expr)
|
||||
raise ArgumentError, options[:locale].t("errors.argument.include") unless template_name
|
||||
render_target = context.evaluate(@template_name_expr)
|
||||
raise ArgumentError, options[:locale].t("errors.argument.render") unless render_target
|
||||
|
||||
# Check to see if this is a renderable drop
|
||||
if render_target.is_a?(Liquid::RenderableDrop)
|
||||
return render_target.render(context, output)
|
||||
end
|
||||
|
||||
# Otherwise it must be a quoted string
|
||||
unless /#{Liquid::QuotedString}+/.match?(@template_name)
|
||||
output << "<!-- #{options[:locale].t('errors.syntax.render')} -->"
|
||||
return
|
||||
end
|
||||
|
||||
template_name = render_target
|
||||
|
||||
partial = PartialCache.load(
|
||||
template_name,
|
||||
|
||||
@@ -75,9 +75,8 @@ class RenderTagTest < Minitest::Test
|
||||
def test_dynamically_choosen_templates_are_not_allowed
|
||||
Liquid::Template.file_system = StubFileSystem.new('snippet' => 'should not be rendered')
|
||||
|
||||
assert_raises(Liquid::SyntaxError) do
|
||||
Liquid::Template.parse("{% assign name = 'snippet' %}{% render name %}")
|
||||
end
|
||||
assert_equal("<!-- Syntax error in tag 'render' - Template name must be a quoted string -->",
|
||||
Liquid::Template.parse("{% assign name = 'snippet' %}{% render name %}").render!)
|
||||
end
|
||||
|
||||
def test_include_tag_caches_second_read_of_same_partial
|
||||
|
||||
Reference in New Issue
Block a user