The Curly template language allows separating your logic from the structure of your HTML templates.
The Curly template language allows separating your logic from the structure of your HTML templates.
[!WARNING] This gem is not used in Zendesk services anymore and won’t be updated. Curly 4.0.0 will be the final released version.
Curly is a template language that completely separates structure and logic. Instead of interspersing your HTML with snippets of Ruby, all logic is moved to a presenter class.
Installing Curly is as simple as running gem install curly-templates. If you're
using Bundler to manage your dependencies, add this to your Gemfile
gem 'curly-templates'
Curly can also install an application layout file, replacing the .erb file commonly
created by Rails. If you wish to use this, run the curly:install generator.
$ rails generate curly:install
In order to use Curly for a view or partial, use the suffix .curly instead of
.erb, e.g. app/views/posts/_comment.html.curly. Curly will look for a
corresponding presenter class named Posts::CommentPresenter. By convention,
these are placed in app/presenters/, so in this case the presenter would
reside in app/presenters/posts/comment_presenter.rb. Note that presenters
for partials are not prepended with an underscore.
Add some HTML to the partial template along with some Curly components:
The presenter will be responsible for providing the data for the components. Add the necessary Ruby code to the presenter:
# app/presenters/posts/comment_presenter.rb
class Posts::CommentPresenter
#
# {{title}}
#
#
#
# {{body}}
#
#
#
class ApplicationLayout
...
In Curly you would instead declare it in the presenter:
class Posts::ShowPresenter < Curly::Presenter
presents :post
def cache_key
[@post, signed_in?]
end
end
Likewise, you can add a #cache_duration method if you wish to automatically expire
the fragment cache:
class Posts::ShowPresenter < Curly::Presenter
...
def cache_duration
30.minutes
end
end
In order to set any cache option, define a #cache_options method that
returns a Hash of options:
class Posts::ShowPresenter < Curly::Presenter
...
def cache_options
{ compress: true, namespace: "my-app" }
end
end
Static caching will only be enabled for presenters that define a non-nil #cache_key
method (see Dynamic Caching.)
In order to make a deploy expire the cache for a specific view, set the version of the
view to something new, usually by incrementing by one:
class Posts::ShowPresenter < Curly::Presenter
version 3
def cache_key
# Some objects
end
end
This will change the cache keys for all instances of that view, effectively expiring the old cache entries.
This works well for views, or for partials that are rendered in views that themselves are not cached. If the partial is nested within a view that is cached, however, the outer cache will not be expired. The solution is to register that the inner partial is a dependency of the outer one such that Curly can automatically deduce that the outer partial cache should be expired:
class Posts::ShowPresenter < Curly::Presenter
version 3
depends_on 'posts/comment'
def cache_key
# Some objects
end
end
class Posts::CommentPresenter < Curly::Presenter
version 4
def cache_key
# Some objects
end
end
Now, if the version of Posts::CommentPresenter is bumped, the cache keys for both
presenters would change. You can register any number of view paths with depends_on.
Curly integrates well with the
caching mechanism in Rails 4 (or
Cache Digests in Rails 3), so the dependencies
defined with depends_on will be tracked by Rails. This will allow you to deploy changes
to your templates and have the relevant caches automatically expire.
Thanks to Zendesk for sponsoring the work on Curly.
Copyright (c) 2013 Daniel Schierbeck (@dasch), Zendesk Inc.
Licensed under the Apache License Version 2.0.
No open issues yet, or sync has not completed.