json liquid filter

did committed Aug 17, 2015
commit 68d4a10e23b46fab2658566d36d6c3fa9ad2ef83
Showing 3 changed files with 110 additions and 0 deletions
locomotive/steam/liquid/filters/json.rb b/lib/locomotive/steam/liquid/filters/json.rb +42 -0
@@ @@ -0,0 +1,42 @@
+ module Locomotive
+ module Steam
+ module Liquid
+ module Filters
+ module Json
+
+ def json(input, fields = nil)
+ if fields && fields.is_a?(String)
+ fields = fields.split(',').map(&:strip)
+ end
+
+ if fields.blank?
+ input.to_json
+ elsif input.respond_to?(:each)
+ if fields.size == 1
+ input.map { |object| object[fields.first].to_json }.join(',')
+ else
+ input.map { |object| "{" + object_to_json(object, fields) + "}" }.join(',')
+ end
+ else
+ object_to_json(input, fields)
+ end
+ end
+
+ protected
+
+ def object_to_json(input, fields)
+ [].tap do |output|
+ fields.each do |field|
+ output << %("#{field}":#{input[field].to_json})
+ end
+ end.join(',')
+ end
+
+ end
+
+ ::Liquid::Template.register_filter(Json)
+
+ end
+ end
+ end
+ end
spec/support/liquid.rb +11 -0
@@ @@ -9,6 +9,17 @@ def parse_template(source, options = nil)
end
module Liquid
+
+ class TestDrop < Liquid::Drop
+ def initialize(source)
+ @_source = source
+ end
+
+ def before_method(meth)
+ @_source[meth.to_sym]
+ end
+ end
+
class SimpleEventsListener
def initialize
ActiveSupport::Notifications.subscribe(/^steam\.parse\./) do |name, start, finish, id, payload|
spec/unit/liquid/filters/json_spec.rb +57 -0
@@ @@ -0,0 +1,57 @@
+ require 'spec_helper'
+
+ describe Locomotive::Steam::Liquid::Filters::Json do
+
+ include Locomotive::Steam::Liquid::Filters::Json
+
+ let(:input) { nil }
+ subject { json(*input) }
+
+ describe 'adds quotes to a string' do
+
+ let(:input) { 'foo' }
+ it { expect(subject).to eq %("foo") }
+
+ end
+
+ context 'drop' do
+
+ describe 'includes only the fields specified' do
+
+ let(:input) { [Liquid::TestDrop.new(title: 'Acme', body: 'Lorem ipsum'), 'title'] }
+ it { expect(subject).to eq %("title":"Acme") }
+
+ end
+
+ end
+
+ context 'collections' do
+
+ describe 'adds brackets and quotes to a collection' do
+
+ let(:input) { [['foo', 'bar']] }
+ it { expect(subject).to eq %(["foo","bar"]) }
+
+ end
+
+ describe 'includes the first field' do
+
+ let(:input) {
+ [[Liquid::TestDrop.new(title: 'Acme', body: 'Lorem ipsum'),
+ Liquid::TestDrop.new(title: 'Hello world', body: 'Lorem ipsum')], 'title'] }
+ it { expect(subject).to eq %("Acme","Hello world") }
+
+ end
+
+ describe 'includes the specified fields' do
+
+ let(:input) {
+ [[Liquid::TestDrop.new(title: 'Acme', body: 'Lorem ipsum', date: '2013-12-13'),
+ Liquid::TestDrop.new(title: 'Hello world', body: 'Lorem ipsum', date: '2013-12-12')], 'title, body'] }
+ it { expect(subject).to eq %({"title":"Acme","body":"Lorem ipsum"},{"title":"Hello world","body":"Lorem ipsum"}) }
+
+ end
+
+ end
+
+ end