diff --git a/lib/jekyll/filters.rb b/lib/jekyll/filters.rb index 2e4a1174..f92c02b1 100644 --- a/lib/jekyll/filters.rb +++ b/lib/jekyll/filters.rb @@ -328,14 +328,23 @@ module Jekyll def as_liquid(item) case item - when String, Numeric, true, false, nil - item.to_liquid when Hash - Hash[item.map { |k, v| [as_liquid(k), as_liquid(v)] }] + pairs = item.map { |k, v| as_liquid([k, v]) } + Hash[pairs] when Array item.map{ |i| as_liquid(i) } else - item.respond_to?(:to_liquid) ? as_liquid(item.to_liquid) : item + if item.respond_to?(:to_liquid) + liquidated = item.to_liquid + # prevent infinite recursion for simple types (which return `self`) + if liquidated == item + item + else + as_liquid(liquidated) + end + else + item + end end end end diff --git a/test/test_filters.rb b/test/test_filters.rb index d46d9352..a9fc951d 100644 --- a/test/test_filters.rb +++ b/test/test_filters.rb @@ -160,14 +160,70 @@ class TestFilters < Test::Unit::TestCase end should "call #to_liquid " do - expected = "[{\"name\":\"Jeremiah\",\"v\":1,\"thing\":[{\"kay\":\"jewelers\"}],\"stuff\":true},{\"name\":\"Smathers\",\"v\":1,\"thing\":[{\"kay\":\"jewelers\"}],\"stuff\":true}]" - assert_equal expected, @filter.jsonify([T.new("Jeremiah"), T.new("Smathers")]) + expected = [ + { + "name" => "Jeremiah", + "v" => 1, + "thing" => [ + { + "kay" => "jewelers" + } + ], + "stuff" => true + }, + { + "name" => "Smathers", + "v" => 1, + "thing" => [ + { + "kay" => "jewelers" + } + ], + "stuff" => true + } + ] + result = @filter.jsonify([T.new("Jeremiah"), T.new("Smathers")]) + assert_equal expected, JSON.parse(result) end should "handle hashes with all sorts of weird keys and values" do - my_hash = { "posts" => Array.new(5) { |i| T.new(i) } } - expected = "{\"posts\":[{\"name\":0,\"v\":1,\"thing\":[{\"kay\":\"jewelers\"}],\"stuff\":true},{\"name\":1,\"v\":1,\"thing\":[{\"kay\":\"jewelers\"}],\"stuff\":true},{\"name\":2,\"v\":1,\"thing\":[{\"kay\":\"jewelers\"}],\"stuff\":true},{\"name\":3,\"v\":1,\"thing\":[{\"kay\":\"jewelers\"}],\"stuff\":true},{\"name\":4,\"v\":1,\"thing\":[{\"kay\":\"jewelers\"}],\"stuff\":true}]}" - assert_equal expected, @filter.jsonify(my_hash) + my_hash = { "posts" => Array.new(3) { |i| T.new(i) } } + expected = { + "posts" => [ + { + "name" => 0, + "v" => 1, + "thing" => [ + { + "kay" => "jewelers" + } + ], + "stuff" => true + }, + { + "name" => 1, + "v" => 1, + "thing" => [ + { + "kay" => "jewelers" + } + ], + "stuff" => true + }, + { + "name" => 2, + "v" => 1, + "thing" => [ + { + "kay" => "jewelers" + } + ], + "stuff" => true + } + ] + } + result = @filter.jsonify(my_hash) + assert_equal expected, JSON.parse(result) end end