Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions lib/curly/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,52 @@ def compile_collection(block)
output <<-RUBY
presenters << presenter
options_stack << options
buffers << buffer

items = Array(#{method_call})

cache_keys = items.each_with_index.map {|item, index|
options = options.merge("#{name}" => item, "#{counter}" => index + 1)
item_presenter_key = ::#{item_presenter_class}.new(self, options).cache_key

ActiveSupport::Cache.expand_cache_key(item_presenter_key) if item_presenter_key.present?
}.compact

cached_fragments = Rails.cache.read_multi(*cache_keys)

items.each_with_index do |item, index|
options = options.merge("#{name}" => item, "#{counter}" => index + 1)
presenter = ::#{item_presenter_class}.new(self, options)

if cached_fragments.key?(presenter.cache_key)
buffers.last << cached_fragments[presenter.cache_key]
next
end

render_with_caching = proc do |&block|
value = block.call

if presenter.cache_key
Rails.cache.write(presenter.cache_key, value)
end

value
end

buffers.last << render_with_caching.call do
buffer = ActiveSupport::SafeBuffer.new
RUBY

@presenter_classes.push(item_presenter_class)
compile(block.nodes)
@presenter_classes.pop

output <<-RUBY
buffer
end
end

buffer = buffers.pop
options = options_stack.pop
presenter = presenters.pop
RUBY
Expand Down
15 changes: 15 additions & 0 deletions spec/collection_blocks_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
def name
@item
end

def cache_key
@item
end
end
end

Expand Down Expand Up @@ -75,4 +79,15 @@ def number

render("{{*items}}<{{*parts}}[{{number}}]{{/parts}}>{{/items}}").should == "<[1][2]><[3][4]>"
end

example "cached rendering" do
define_presenter do
def items
["one", "two", "three"]
end
end

render("{{*items}}<{{name}}>{{/items}}").should == "<one><two><three>"
render("{{*items}}<{{name}}>{{/items}}").should == "<one><two><three>"
end
end