diff --git a/lib/liquid/variable.rb b/lib/liquid/variable.rb index 0c04fe2..2c317a8 100644 --- a/lib/liquid/variable.rb +++ b/lib/liquid/variable.rb @@ -23,9 +23,9 @@ module Liquid if match[2].match(/#{FilterSeparator}\s*(.*)/o) filters = Regexp.last_match(1).scan(FilterParser) filters.each do |f| - if matches = f.match(/\s*(\w+)/) + if matches = f.match(/\s*(\w+)(?:\s*#{FilterArgumentSeparator}(.*))?/) filtername = matches[1] - filterargs = f.scan(/(?:#{FilterArgumentSeparator}|#{ArgumentSeparator})\s*(#{QuotedFragment})/o).flatten + filterargs = matches[2].to_s.scan(/(?:\A|#{ArgumentSeparator})\s*((?:\w+\s*\:\s*)?#{QuotedFragment})/o).flatten @filters << [filtername.to_sym, filterargs] end end @@ -36,9 +36,16 @@ module Liquid def render(context) return '' if @name.nil? @filters.inject(context[@name]) do |output, filter| - filterargs = filter[1].to_a.collect do |a| - context[a] + filterargs = [] + keyword_args = {} + filter[1].to_a.each do |a| + if matches = a.match(/\A#{TagAttributes}\z/o) + keyword_args[matches[1]] = context[matches[2]] + else + filterargs << context[a] + end end + filterargs << keyword_args unless keyword_args.empty? begin output = context.invoke(filter[0], output, *filterargs) rescue FilterNotFound diff --git a/test/liquid/filter_test.rb b/test/liquid/filter_test.rb index f24a70c..d924c6a 100644 --- a/test/liquid/filter_test.rb +++ b/test/liquid/filter_test.rb @@ -16,6 +16,12 @@ module CanadianMoneyFilter end end +module SubstituteFilter + def substitute(input, params={}) + input.gsub(/%\{(\w+)\}/) { |match| params[$1] } + end +end + class FiltersTest < Test::Unit::TestCase include Liquid @@ -92,6 +98,13 @@ class FiltersTest < Test::Unit::TestCase assert_equal 1000, Variable.new("var | xyzzy").render(@context) end + + def test_filter_with_keyword_arguments + @context['surname'] = 'john' + @context.add_filters(SubstituteFilter) + output = Variable.new(%! 'hello %{first_name}, %{last_name}' | substitute: first_name: surname, last_name: 'doe' !).render(@context) + assert_equal 'hello john, doe', output + end end class FiltersInTemplate < Test::Unit::TestCase diff --git a/test/liquid/variable_test.rb b/test/liquid/variable_test.rb index 7bdef35..58a1ee3 100644 --- a/test/liquid/variable_test.rb +++ b/test/liquid/variable_test.rb @@ -107,6 +107,12 @@ class VariableTest < Test::Unit::TestCase var = Variable.new(%| test.test |) assert_equal 'test.test', var.name end + + def test_filter_with_keyword_arguments + var = Variable.new(%! hello | things: greeting: "world", farewell: 'goodbye'!) + assert_equal 'hello', var.name + assert_equal [[:things,["greeting: \"world\"","farewell: 'goodbye'"]]], var.filters + end end