From a5c1f7b6f50d6aa3beacd98a96125c6431aaa88b Mon Sep 17 00:00:00 2001 From: James Reid-Smith Date: Thu, 11 Sep 2014 23:07:54 +0000 Subject: [PATCH] Moved parsing of partials to parse time of include tags if it's possible (eg. context not required to know template name) --- lib/liquid/tags/include.rb | 40 +++++++++++++++++++---- test/integration/tags/include_tag_test.rb | 21 ++++++++++++ 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/lib/liquid/tags/include.rb b/lib/liquid/tags/include.rb index e367ac3..490d281 100644 --- a/lib/liquid/tags/include.rb +++ b/lib/liquid/tags/include.rb @@ -30,6 +30,11 @@ module Liquid @attributes[key] = value end + if partial_parsable_at_parse_time? + source = read_template_from_file_system_at_parse + @partial = Liquid::Template.parse(source, pass_options) + end + else raise SyntaxError.new(options[:locale].t("errors.syntax.include".freeze)) end @@ -66,17 +71,21 @@ module Liquid template_name = context[@template_name] if cached = cached_partials[template_name] - return cached + cached + else + if @partial && context.registers[:file_system].nil? + partial = @partial + else + partial = Liquid::Template.parse(read_template_from_file_system(context), pass_options) + end + cached_partials[template_name] = partial + context.registers[:cached_partials] = cached_partials + partial end - source = read_template_from_file_system(context) - partial = Liquid::Template.parse(source, pass_options) - cached_partials[template_name] = partial - context.registers[:cached_partials] = cached_partials - partial end def read_template_from_file_system(context) - file_system = context.registers[:file_system] || Liquid::Template.file_system + file_system = context.registers[:file_system] || parsed_file_system || Liquid::Template.file_system # make read_template_file call backwards-compatible. case file_system.method(:read_template_file).arity @@ -89,6 +98,23 @@ module Liquid end end + def read_template_from_file_system_at_parse + parsed_file_system.read_template_file(parsed_template_name) + end + + def parsed_file_system + options[:file_system] + end + + def partial_parsable_at_parse_time? + template_name_is_string_constant = parsed_template_name.is_a?(String) + options[:file_system] && template_name_is_string_constant + end + + def parsed_template_name + Expression.parse(@template_name) + end + def pass_options dont_pass = @options[:include_options_blacklist] return {locale: @options[:locale]} if dont_pass == true diff --git a/test/integration/tags/include_tag_test.rb b/test/integration/tags/include_tag_test.rb index 49267f3..7f07317 100644 --- a/test/integration/tags/include_tag_test.rb +++ b/test/integration/tags/include_tag_test.rb @@ -33,6 +33,13 @@ class TestFileSystem end end +# FileSystems at parse time don't have a context +class ParseFileSystem + def read_template_file(template_path) + 'from ParseFileSystem' + end +end + class OtherFileSystem def read_template_file(template_path, context) 'from OtherFileSystem' @@ -77,6 +84,20 @@ class IncludeTagTest < Minitest::Test Template.parse("{% include 'pick_a_source' %}").render!({}, :registers => {:file_system => OtherFileSystem.new}) end + def test_include_tag_can_use_file_system_at_parse_so_it_can_be_parsed_before_rendered + assert_equal 'from ParseFileSystem', + Template.parse("{% include 'pick_a_source' %}",file_system: ParseFileSystem.new).render!({}) + end + + def test_include_tag_looks_at_file_system_passed_in_registers_over_parse_options + assert_equal 'from OtherFileSystem', + Template.parse("{% include 'pick_a_source' %}",file_system: ParseFileSystem.new).render!({}, :registers => {:file_system => OtherFileSystem.new}) + end + + def test_include_tag_use_parse_option_file_system_even_if_partial_can_be_preparsed + assert_equal 'from ParseFileSystem', + Template.parse("{% include template %}",file_system: ParseFileSystem.new).render!({}) + end def test_include_tag_with assert_template_result "Product: Draft 151cm ",