diff --git a/lib/liquid.rb b/lib/liquid.rb index d102530..cfaccee 100644 --- a/lib/liquid.rb +++ b/lib/liquid.rb @@ -78,8 +78,10 @@ require 'liquid/tokenizer' require 'liquid/parse_context' require 'liquid/partial_cache' require 'liquid/usage' +require 'liquid/register' require 'liquid/static_registers' # Load all the tags of the standard library # Dir["#{__dir__}/liquid/tags/*.rb"].each { |f| require f } +Dir["#{__dir__}/liquid/registers/*.rb"].each { |f| require f } diff --git a/lib/liquid/locales/en.yml b/lib/liquid/locales/en.yml index c0a9aff..f821da6 100644 --- a/lib/liquid/locales/en.yml +++ b/lib/liquid/locales/en.yml @@ -25,3 +25,5 @@ render: "Syntax error in tag 'render' - Template name must be a quoted string" argument: include: "Argument error in tag 'include' - Illegal template name" + disabled: + include: "'include' usage has been disabled in this context, consider using 'render'." diff --git a/lib/liquid/register.rb b/lib/liquid/register.rb new file mode 100644 index 0000000..92d0226 --- /dev/null +++ b/lib/liquid/register.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +module Liquid + class Register + end +end diff --git a/lib/liquid/registers/disabled_tags.rb b/lib/liquid/registers/disabled_tags.rb new file mode 100644 index 0000000..1bf1501 --- /dev/null +++ b/lib/liquid/registers/disabled_tags.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true +module Liquid + class DisabledTags < Register + def initialize + @disabled_tags = Hash.new { |h, k| h[k] = 0 } + end + + def disabled?(tag) + @disabled_tags[tag] > 0 + end + + def disable(tag) + incr(tag) + yield + ensure + decr(tag) + end + + private + + def incr(tag) + @disabled_tags[tag] = @disabled_tags[tag] + 1 + end + + def decr(tag) + @disabled_tags[tag] = @disabled_tags[tag] - 1 + end + end + + Template.register_register('disabled_tags', DisabledTags.new) +end diff --git a/lib/liquid/tags/include.rb b/lib/liquid/tags/include.rb index bbcfb1c..2403097 100644 --- a/lib/liquid/tags/include.rb +++ b/lib/liquid/tags/include.rb @@ -45,6 +45,7 @@ module Liquid end def render_to_output_buffer(context, output) + return output << options[:locale].t("errors.disabled.include") if context.registers['disabled_tags']&.disabled?('include') template_name = context.evaluate(@template_name_expr) raise ArgumentError, options[:locale].t("errors.argument.include") unless template_name diff --git a/lib/liquid/tags/render.rb b/lib/liquid/tags/render.rb index e6c6223..20eacbe 100644 --- a/lib/liquid/tags/render.rb +++ b/lib/liquid/tags/render.rb @@ -22,6 +22,13 @@ module Liquid end def render_to_output_buffer(context, output) + context.registers['disabled_tags']&.disable('include') do + return render_tag(context, output) + end + render_tag(context, output) + 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 diff --git a/lib/liquid/template.rb b/lib/liquid/template.rb index e77ba8a..29062a5 100644 --- a/lib/liquid/template.rb +++ b/lib/liquid/template.rb @@ -92,6 +92,14 @@ module Liquid @tags ||= TagRegistry.new end + def register_register(name, klass) + registers[name.to_s] = klass + end + + def registers + @registers ||= {} + end + def error_mode @error_mode ||= :lax end @@ -203,6 +211,8 @@ module Liquid context.add_filters(args.pop) end + registers.merge!(Template.registers) if Template.registers.is_a?(Hash) + # Retrying a render resets resource usage context.resource_limits.reset