A simple (< 100 lines of code) but powerful exhibit/presenter implementation. It's framework agnostic: works with Rails, Padrino or just Sinatra.
Since version 0.2.0 Showcase is bundled with a set of optional "traits" you can pick and choose to augment your presenters with additional sugar (available in Rails 3+ only).
Why should I use presenters in my Rails app?
See Avdi's Exhibits introductory post.
Installation
Add this line to your application's Gemfile:
gem 'showcase'
And then execute:
$ bundle
Or install it yourself as:
$ gem install showcase
Usage
With Rails, you're already set, move on! With Padrino, include Showcase::Helpers::Present
in your app helpers
block.
helpers do
include Showcase::Helpers::Present
end
You can now instantiate new presenters in your views using the included helpers:
# this is the object that needs to be presented
person = Person.new
# automatically infers presenter class to use based on person's class name
present(person) # => returns a PersonPresenter instance
# you can also explicitly tell what presenter to use
present(person, AdminPresenter) # => returns an AdminPresenter instance
# explicit presenter and context
present(person, PersonPresenter, context)
# maps each person in the collection with a presenter
present_collection([person]) # => returns an array of PersonPresenters
Define your presenters i.e. in a app/presenters
folder:
class ProjectPresenter < Showcase::Presenter
# automatically wraps the attribute into a PersonPresenter
presents :person
# automatically wraps the attribute into an AdminPresenter
presents :person, with: AdminPresenter
# expects project.tasks to return an enumerable. automatically wraps each task
# in a TaskPresenter presenter
presents_collection :tasks
# you can use `view_context`, or the shortcut `h`, to access the context.
# `object` refers to the object being presented
def title
h.link_to object.title, object
end
end
Rails
Generators
Showcase comes with a generator to create new presenters a little faster:
rails generate showcase:presenter User
Will generate app/presenters/user_presenter.rb
. If your Rails app has the file
app/presenters/base_presenter.rb
, the newly created presenter will inherit
from BasePresenter
instead of Showcase::Presenter
.
Traits
Please read the tests for a detailed explanation of each method available.
Showcase::Traits::Record
To be used to present ActiveModel-based records. Inside your presenter, include the trait like this:
class ProjectPresenter < Showcase::Presenter
include Showcase::Traits::Record
end
#dom_id
present(@project).dom_id # => "project_12"
#dom_class
present(@project).dom_class # => "project"
#box
Super useful in acceptance testing to check the presence of a record inside a view:
<% present(@project).box(class: 'big') do %>
<p>Hi there!</p>
<% end %>
Produces the following:
<div class="project big" id="project_12">
<p>Hi there</p>
</div>
Additional HTML attributes can be optionally specified within a config block inside the presenter:
class ProjectPresenter < Showcase::Presenter
include Showcase::Traits::Record
box do |c|
c.html_options class: 'another-class', role: 'project'
end
end
Showcase::Traits::LinkTo
Adds a nice DSL to declare links within your presenter.
class ProjectPresenter < Showcase::Presenter
include Showcase::Traits::LinkTo
link_to do |c|
c.url h.project_path(self)
c.label name
c.active h.controller_name == 'projects'
c.active_class 'current'
c.html_options role: 'label'
end
link_to :tasks do
c.url h.project_tasks_path(self)
c.label "Tasks"
end
end
In your views:
<%= project.url %>
<%= project.tasks_url %>
<%= project.link_active? %>
<%= project.tasks_link_active? %>
<%= project.link %>
<%= project.tasks_link %>
<%= project.link('Alternative label') %>
<%= project.link(class: 'additional_class') %>
<%= project.link do %>
Link content!
<% end %>
Showcase::Traits::Share
Useful to produce social share links:
class ProjectPresenter < Showcase::Presenter
include Showcase::Traits::Share
share do |c|
c.url h.project_path(self)
c.text name
c.image_url cover_image
end
end
In your views:
<%= project.twitter_share_url %>
<%= project.twitter_share_link %>
<%= project.twitter_share_link('Alternative label') %>
<%= project.twitter_share_link(class: 'additional_class') %>
<%= project.twitter_share_link do %>
Link content!
<% end %>
<%= project.facebook_share_link %>
<%= project.gplus_share_link %>
<%= project.pinterest_share_link %>
<%= project.linkedin_share_link %>
Showcase::Traits::Seo
Useful to produce SEO meta tags (title, description, Facebook OpenGraph, Twitter cards, and canonical URLs):
class ProjectPresenter < Showcase::Presenter
include Showcase::Traits::Seo
seo do |c|
c.title name
c.description [ description, 'Fallback description if blank' ]
c.image_url cover_thumb_image
c.canonical_url h.project_url(self)
end
end
In your views:
<% content_for(:head) do %>
<%= present(@project).seo_tags(title_suffix: ' - BaseClump') %>
<% end %>
Testing
Install gems:
$ bundle
$ bundle exec appraisal
Launch tests:
bundle exec appraisal rake
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request