From 072c12dc47ebd65975d48331e6d9d20fdf7795d8 Mon Sep 17 00:00:00 2001 From: Simon Eskildsen Date: Thu, 29 Aug 2013 19:11:07 -0400 Subject: [PATCH] Localize errors in Liquid --- lib/liquid/block.rb | 15 +++++++++------ lib/liquid/htmltags.rb | 2 +- lib/liquid/locales/en.yml | 21 +++++++++++++++++++-- lib/liquid/tags/assign.rb | 2 +- lib/liquid/tags/capture.rb | 2 +- lib/liquid/tags/case.rb | 6 +++--- lib/liquid/tags/cycle.rb | 2 +- lib/liquid/tags/for.rb | 6 +++--- lib/liquid/tags/if.rb | 5 ++--- lib/liquid/tags/include.rb | 2 +- test/liquid/assign_test.rb | 6 ++++++ test/liquid/template_test.rb | 1 + test/test_helper.rb | 7 +++++++ 13 files changed, 55 insertions(+), 22 deletions(-) diff --git a/lib/liquid/block.rb b/lib/liquid/block.rb index a5c3b1e..ed7f7ac 100644 --- a/lib/liquid/block.rb +++ b/lib/liquid/block.rb @@ -41,7 +41,7 @@ module Liquid unknown_tag($1, $2, tokens) end else - raise SyntaxError, "Tag '#{token}' was not properly terminated with regexp: #{TagEnd.inspect} " + raise SyntaxError.new(options[:locale].t("errors.syntax.tag_termination", :token => token, :tag_end => TagEnd.inspect)) end when IsVariable new_var = create_variable(token) @@ -80,11 +80,14 @@ module Liquid def unknown_tag(tag, params, tokens) case tag when 'else' - raise SyntaxError, "#{block_name} tag does not expect else tag" + raise SyntaxError.new(options[:locale].t("errors.syntax.unexpected_else", + :block_name => block_name)) when 'end' - raise SyntaxError, "'end' is not a valid delimiter for #{block_name} tags. use #{block_delimiter}" + raise SyntaxError.new(options[:locale].t("errors.syntax.invalid_delimiter", + :block_name => block_name, + :block_delimiter => block_delimiter)) else - raise SyntaxError, "Unknown tag '#{tag}'" + raise SyntaxError.new(options[:locale].t("errors.syntax.unknown_tag", :tag => tag)) end end @@ -100,7 +103,7 @@ module Liquid token.scan(ContentOfVariable) do |content| return Variable.new(content.first, @options) end - raise SyntaxError.new("Variable '#{token}' was not properly terminated with regexp: #{VariableEnd.inspect} ") + raise SyntaxError.new(options[:locale].t("errors.syntax.tag_termination", :token => token, :tag_end => TagEnd.inspect)) end def render(context) @@ -110,7 +113,7 @@ module Liquid protected def assert_missing_delimitation! - raise SyntaxError.new("#{block_name} tag was never closed") + raise SyntaxError.new(options[:locale].t("errors.syntax.tag_never_closed", :block_name => block_name)) end def render_all(list, context) diff --git a/lib/liquid/htmltags.rb b/lib/liquid/htmltags.rb index 62a5389..05b0419 100644 --- a/lib/liquid/htmltags.rb +++ b/lib/liquid/htmltags.rb @@ -11,7 +11,7 @@ module Liquid @attributes[key] = value end else - raise SyntaxError.new("Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3") + raise SyntaxError.new(options[:locale].t("errors.syntax.table_row")) end super diff --git a/lib/liquid/locales/en.yml b/lib/liquid/locales/en.yml index 0ec28e1..f2c5419 100644 --- a/lib/liquid/locales/en.yml +++ b/lib/liquid/locales/en.yml @@ -5,5 +5,22 @@ undefined_interpolation: "Undefined key :key for interpolation in translation :name" template: argument_hash_or_context: "Expect Hash or Liquid::Context as parameter" - syntax_error: - tag_termination: "Tag ':token' was not properly terminated with regexp: :inspection" + syntax: + assign: "Syntax Error in 'assign' - Valid syntax: assign [var] = [source]" + capture: "Syntax Error in 'capture' - Valid syntax: capture [var]" + case: "Syntax Error in 'case' - Valid syntax: case [condition]" + case_invalid_when: "Syntax Error in tag 'case' - Valid when condition: {% when [condition] [or condition2...] %}" + case_invalid_else: "Syntax Error in tag 'case' - Valid else condition: {% else %} (no parameters) " + cycle: "Syntax Error in 'cycle' - Valid syntax: cycle [name :] var [, var2, var3 ...]" + for: "Syntax Error in 'for loop' - Valid syntax: for [item] in [collection]" + for_invalid_in: "For loops require an 'in' clause" + for_invalid_attribute: "Invalid attribute in for loop. Valid attributes are limit and offset" + if: "Syntax Error in tag 'if' - Valid syntax: if [expression]" + include: "Error in tag 'include' - Valid syntax: include '[template]' (with|for) [object|collection]" + unknown_tag: "Unknown tag '%{tag}'" + invalid_delimiter: "'end' is not a valid delimiter for %{block_name} tags. use %{block_delimiter}" + unexpected_else: "%{block_name} tag does not expect else tag" + tag_termination: "Tag '%{token}' was not properly terminated with regexp: %{tag_end}" + tag_never_closed: "'%{block_name}' tag was never closed" + meta_syntax_error: "Liquid syntax error: #{e.message}" + table_row: "Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3" diff --git a/lib/liquid/tags/assign.rb b/lib/liquid/tags/assign.rb index 34fdf19..45c6bed 100644 --- a/lib/liquid/tags/assign.rb +++ b/lib/liquid/tags/assign.rb @@ -16,7 +16,7 @@ module Liquid @to = $1 @from = Variable.new($2) else - raise SyntaxError.new("Syntax Error in 'assign' - Valid syntax: assign [var] = [source]") + raise SyntaxError.new options[:locale].t("errors.syntax.assign") end super diff --git a/lib/liquid/tags/capture.rb b/lib/liquid/tags/capture.rb index 4f5b34c..92b9950 100644 --- a/lib/liquid/tags/capture.rb +++ b/lib/liquid/tags/capture.rb @@ -18,7 +18,7 @@ module Liquid if markup =~ Syntax @to = $1 else - raise SyntaxError.new("Syntax Error in 'capture' - Valid syntax: capture [var]") + raise SyntaxError.new(options[:locale].t("errors.syntax.capture")) end super diff --git a/lib/liquid/tags/case.rb b/lib/liquid/tags/case.rb index a9b2316..ce2ad88 100644 --- a/lib/liquid/tags/case.rb +++ b/lib/liquid/tags/case.rb @@ -9,7 +9,7 @@ module Liquid if markup =~ Syntax @left = $1 else - raise SyntaxError.new("Syntax Error in tag 'case' - Valid syntax: case [condition]") + raise SyntaxError.new(options[:locale].t("errors.syntax.case")) end super @@ -50,7 +50,7 @@ module Liquid while markup # Create a new nodelist and assign it to the new block if not markup =~ WhenSyntax - raise SyntaxError.new("Syntax Error in tag 'case' - Valid when condition: {% when [condition] [or condition2...] %} ") + raise SyntaxError.new(options[:locale].t("errors.syntax.case_invalid_when")) end markup = $2 @@ -63,7 +63,7 @@ module Liquid def record_else_condition(markup) if not markup.strip.empty? - raise SyntaxError.new("Syntax Error in tag 'case' - Valid else condition: {% else %} (no parameters) ") + raise SyntaxError.new(options[:locale].t("errors.syntax.case_invalid_else")) end block = ElseCondition.new diff --git a/lib/liquid/tags/cycle.rb b/lib/liquid/tags/cycle.rb index e970dfb..de81142 100644 --- a/lib/liquid/tags/cycle.rb +++ b/lib/liquid/tags/cycle.rb @@ -24,7 +24,7 @@ module Liquid @variables = variables_from_string(markup) @name = "'#{@variables.to_s}'" else - raise SyntaxError.new("Syntax Error in 'cycle' - Valid syntax: cycle [name :] var [, var2, var3 ...]") + raise SyntaxError.new(options[:locale].t("errors.syntax.cycle")) end super end diff --git a/lib/liquid/tags/for.rb b/lib/liquid/tags/for.rb index 69fc9d3..5902704 100644 --- a/lib/liquid/tags/for.rb +++ b/lib/liquid/tags/for.rb @@ -128,14 +128,14 @@ module Liquid @attributes[key] = value end else - raise SyntaxError.new("Syntax Error in 'for loop' - Valid syntax: for [item] in [collection]") + raise SyntaxError.new(options[:locale].t("errors.syntax.for")) end end def strict_parse(markup) p = Parser.new(markup) @variable_name = p.consume(:id) - raise SyntaxError, "For loops require an 'in' clause" unless p.id?('in') + raise SyntaxError.new(options[:locale].t("errors.syntax.for_invalid_in")) unless p.id?('in') @collection_name = p.expression @name = "#{@variable_name}-#{@collection_name}" @reversed = p.id?('reversed') @@ -143,7 +143,7 @@ module Liquid @attributes = {} while p.look(:id) && p.look(:colon, 1) unless attribute = p.id?('limit') || p.id?('offset') - raise SyntaxError, "Invalid attribute in for loop. Valid attributes are limit and offset" + raise SyntaxError.new(options[:locale].t("errors.syntax.for_invalid_attribute")) end p.consume val = p.expression diff --git a/lib/liquid/tags/if.rb b/lib/liquid/tags/if.rb index ac1767d..c376f6c 100644 --- a/lib/liquid/tags/if.rb +++ b/lib/liquid/tags/if.rb @@ -10,7 +10,6 @@ module Liquid # There are {% if count < 5 %} less {% else %} more {% endif %} items than you need. # class If < Block - SyntaxHelp = "Syntax Error in tag 'if' - Valid syntax: if [expression]" Syntax = /(#{QuotedFragment})\s*([=!<>a-z_]+)?\s*(#{QuotedFragment})?/o ExpressionsAndOperators = /(?:\b(?:\s?and\s?|\s?or\s?)\b|(?:\s*(?!\b(?:\s?and\s?|\s?or\s?)\b)(?:#{QuotedFragment}|\S+)\s*)+)/o @@ -54,14 +53,14 @@ module Liquid def lax_parse(markup) expressions = markup.scan(ExpressionsAndOperators).reverse - raise(SyntaxError, SyntaxHelp) unless expressions.shift =~ Syntax + raise(SyntaxError.new(options[:locale].t("errors.syntax.if"))) unless expressions.shift =~ Syntax condition = Condition.new($1, $2, $3) while not expressions.empty? operator = (expressions.shift).to_s.strip - raise(SyntaxError, SyntaxHelp) unless expressions.shift.to_s =~ Syntax + raise(SyntaxError.new(options[:locale].t("errors.syntax.if"))) unless expressions.shift.to_s =~ Syntax new_condition = Condition.new($1, $2, $3) new_condition.send(operator.to_sym, condition) diff --git a/lib/liquid/tags/include.rb b/lib/liquid/tags/include.rb index 42eff17..76448f8 100644 --- a/lib/liquid/tags/include.rb +++ b/lib/liquid/tags/include.rb @@ -29,7 +29,7 @@ module Liquid end else - raise SyntaxError.new("Error in tag 'include' - Valid syntax: include '[template]' (with|for) [object|collection]") + raise SyntaxError.new(options[:locale].t("errors.syntax.include")) end super diff --git a/test/liquid/assign_test.rb b/test/liquid/assign_test.rb index d1eb615..f4edb9a 100644 --- a/test/liquid/assign_test.rb +++ b/test/liquid/assign_test.rb @@ -18,4 +18,10 @@ class AssignTest < Test::Unit::TestCase '{% assign foo = values | split: "," %}.{{ foo[1] }}.', 'values' => "foo,bar,baz") end + + def test_assign_syntax_error + assert_match_syntax_error(/assign/, + '{% assign foo not values %}.', + 'values' => "foo,bar,baz") + end end # AssignTest diff --git a/test/liquid/template_test.rb b/test/liquid/template_test.rb index 939d4e8..72a1264 100644 --- a/test/liquid/template_test.rb +++ b/test/liquid/template_test.rb @@ -146,6 +146,7 @@ class TemplateTest < Test::Unit::TestCase def test_sets_default_localization_in_document t = Template.new + t.parse('') assert_instance_of I18n, t.root.options[:locale] end diff --git a/test/test_helper.rb b/test/test_helper.rb index aa2f6e7..e1f12f0 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -40,6 +40,13 @@ module Test assert_match expected, Template.parse(template).render(assigns) end + def assert_match_syntax_error(match, template, registers = {}) + exception = assert_raise(Liquid::SyntaxError) { + Template.parse(template).render(assigns) + } + assert_match match, exception.message + end + def with_error_mode(mode) old_mode = Liquid::Template.error_mode Liquid::Template.error_mode = mode