Project

showcase

0.02
No commit activity in last 3 years
No release in over 3 years
A barebone and framework agnostic presenter implementation
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

Runtime

 Project Readme

Showcase Build Status Coverage Status

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

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request