With ERB you can fragment cache individual records in a list view like so:
<% @items.each do |item| %>
<% cache item do %>
<%= item.name %>
<% end %>
<% end %>
Thus, the second time the list is viewed, each rendered item will be loaded from cache. Is it possible to use this same approach when using Liquid templates? The template might look something like:
{% for item in items %}
{{ item.name }}
{% endfor %}
and rendered with:
template = Liquid::Template.parse(template)
template.render('items' => @items)
When it loops over the items, I'd like to be able to fragment cache each one. Any pointers?
You can define custom tags in liquid, for example if you put this in an initializer
class Cacher < Liquid::Block
def initialize(tag_name, markup, tokens)
super
@key= markup.to_s
end
def render(context)
Rails.cache.fetch(@key) do
super
end
end
end
Liquid::Template.register_tag('cache', Cacher)
Then you can do
{% cache "some_key" %}
...
{% endcache %}
Be very careful with how you construct the cache key. You of course want to avoid clashes, but you also probably don't want people to be able to read arbitrary keys from your memcache store (which this code does). How match this matters depends on who has access to this in your app. One strategy would be to namespace cache keys.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With