From d0184555d9e3a2b9bb2be939a5dc983f4f6e41d9 Mon Sep 17 00:00:00 2001 From: Dylan Smith Date: Wed, 20 Jun 2012 11:07:11 -0400 Subject: [PATCH] Allow tablerow to work with any Enumerable. Closes #132 --- lib/liquid.rb | 1 + lib/liquid/htmltags.rb | 9 ++++---- lib/liquid/tags/for.rb | 38 ++++--------------------------- lib/liquid/utils.rb | 31 +++++++++++++++++++++++++ test/liquid/tags/html_tag_test.rb | 18 +++++++++++++++ 5 files changed, 59 insertions(+), 38 deletions(-) create mode 100644 lib/liquid/utils.rb diff --git a/lib/liquid.rb b/lib/liquid.rb index 3a30a69..7c4b327 100644 --- a/lib/liquid.rb +++ b/lib/liquid.rb @@ -60,6 +60,7 @@ require 'liquid/htmltags' require 'liquid/standardfilters' require 'liquid/condition' require 'liquid/module_ex' +require 'liquid/utils' # Load all the tags of the standard library # diff --git a/lib/liquid/htmltags.rb b/lib/liquid/htmltags.rb index 1763587..33c85c0 100644 --- a/lib/liquid/htmltags.rb +++ b/lib/liquid/htmltags.rb @@ -20,11 +20,10 @@ module Liquid def render(context) collection = context[@collection_name] or return '' - if @attributes['limit'] or @attributes['offset'] - limit = context[@attributes['limit']] || -1 - offset = context[@attributes['offset']] || 0 - collection = collection[offset.to_i..(limit.to_i + offset.to_i - 1)] - end + from = @attributes['offset'] ? context[@attributes['offset']].to_i : 0 + to = @attributes['limit'] ? from + context[@attributes['limit']].to_i - 1 : nil + + collection = Utils.slice_collection_using_each(collection, from, to) length = collection.length diff --git a/lib/liquid/tags/for.rb b/lib/liquid/tags/for.rb index c66a681..a76b875 100644 --- a/lib/liquid/tags/for.rb +++ b/lib/liquid/tags/for.rb @@ -86,10 +86,10 @@ module Liquid limit = context[@attributes['limit']] to = limit ? limit.to_i + from : nil - - - segment = slice_collection_using_each(collection, from, to) - + + + segment = Utils.slice_collection_using_each(collection, from, to) + return render_else(context) if segment.empty? segment.reverse! if @reversed @@ -119,30 +119,6 @@ module Liquid end result end - - def slice_collection_using_each(collection, from, to) - segments = [] - index = 0 - yielded = 0 - - # Maintains Ruby 1.8.7 String#each behaviour on 1.9 - return [collection] if non_blank_string?(collection) - - collection.each do |item| - - if to && to <= index - break - end - - if from <= index - segments << item - end - - index += 1 - end - - segments - end private @@ -151,11 +127,7 @@ module Liquid end def iterable?(collection) - collection.respond_to?(:each) || non_blank_string?(collection) - end - - def non_blank_string?(collection) - collection.is_a?(String) && collection != '' + collection.respond_to?(:each) || Utils.non_blank_string?(collection) end end diff --git a/lib/liquid/utils.rb b/lib/liquid/utils.rb new file mode 100644 index 0000000..6058a92 --- /dev/null +++ b/lib/liquid/utils.rb @@ -0,0 +1,31 @@ +module Liquid + module Utils + def self.slice_collection_using_each(collection, from, to) + segments = [] + index = 0 + yielded = 0 + + # Maintains Ruby 1.8.7 String#each behaviour on 1.9 + return [collection] if non_blank_string?(collection) + + collection.each do |item| + + if to && to <= index + break + end + + if from <= index + segments << item + end + + index += 1 + end + + segments + end + + def self.non_blank_string?(collection) + collection.is_a?(String) && collection != '' + end + end +end diff --git a/test/liquid/tags/html_tag_test.rb b/test/liquid/tags/html_tag_test.rb index c54234d..da02da6 100644 --- a/test/liquid/tags/html_tag_test.rb +++ b/test/liquid/tags/html_tag_test.rb @@ -3,6 +3,18 @@ require 'test_helper' class HtmlTagTest < Test::Unit::TestCase include Liquid + class ArrayDrop < Liquid::Drop + include Enumerable + + def initialize(array) + @array = array + end + + def each(&block) + @array.each(&block) + end + end + def test_html_table assert_template_result("\n 1 2 3 \n 4 5 6 \n", @@ -36,4 +48,10 @@ class HtmlTagTest < Test::Unit::TestCase 'collections' => {'frontpage' => [1,2,3,4,5,6]}) end + + def test_enumerable_drop + assert_template_result("\n 1 2 3 \n 4 5 6 \n", + '{% tablerow n in numbers cols:3%} {{n}} {% endtablerow %}', + 'numbers' => ArrayDrop.new([1,2,3,4,5,6])) + end end # HtmlTagTest