Presentability::
Presenter class
Superclass | Object |
Extended With |
|
A presenter (facade) base class.
Declaring Presenters
When you declare a presenter in a Presentability
collection, the result is a subclass of Presentability::Presenter
. The main way of defining a Presenter’s functionality is via the ::expose
method, which marks an attribute of the underlying entity object (the “subject”) for exposure.
class MyPresenter < Presentability::Presenter expose :name end # Assuming `entity_object' has a "name" attribute... presenter = MyPresenter.new( entity_object ) presenter.apply # => { :name => "entity name" }
Presenter
Collections
Setting up classes manually like this is one option, but Presentability
also lets you set them up as a collection, which is what further examples will assume for brevity:
module MyPresenters extend Presentability presenter_for( EntityObject ) do expose :name end end
Complex Exposures
Sometimes you want to do more than just use the presented entity’s values as-is. There are a number of ways to do this.
The first of these is to provide a block when exposing an attribute. The subject of the presenter is available to the block via the subject
method:
require 'time' presenter_for( LogEvent ) do # Turn Time objects into RFC2822-formatted time strings expose :timestamp do self.subject.timestamp.rfc2822 end end
You can also declare the exposure using a regular method with the same name:
require 'time' presenter_for( LogEvent ) do # Turn Time objects into RFC2822-formatted time strings expose :timestamp def timestamp return self.subject.timestamp.rfc2822 end end
This can be used to add presence checks:
require 'time' presenter_for( LogEvent ) do # Require that presented entities have an `id` attribute expose :id do id = self.subject.id or raise "no `id' for %p" % [ self.subject ] raise "`id' for %p is blank!" % [ self.subject ] if id.blank? return id end end
or conditional exposures:
presenter_for( Acme::Product ) do # Truncate the long description if presented as part of a collection expose :detailed_description do desc = self.subject.detailed_description if self.options[:in_collection] return desc[0..15] + '...' else return desc end end end
Exposure Aliases
If you want to expose a field but use a different name in the resulting data structure, you can use the :as
option in the exposure declaration:
presenter_for( LogEvent ) do expose :timestamp, as: :created_at end presenter = MyPresenter.new( log_event ) presenter.apply # => { :created_at => '2023-02-01 12:34:02.155365 -0800' }
Constants
- DEFAULT_EXPOSURE_OPTIONS
The exposure options used by every exposure unless overridden
Attributes
- options R
The presentation options
- subject R
The subject of the presenter, the object that is delegated to when building the representation.
Public Class Methods
Set up an exposure that will delegate to the attribute of the subject with the given name
.
Set up an exposure of a collection with the given name
. This means it will have the :in_collection option set by default.
The Hash of exposures declared by this class
Generate the body an exposure method that delegates to a method with the same name
on its subject.
Enable instantiation by subclasses.
Method definition hook – hook up new methods with the same name as an exposure to its :call option.
Create a new Presenter
for the given subject
.
Public Instance Methods
Apply the exposures to the subject and return the result.
Return a human-readable representation of the object suitable for debugging.
Protected Instance Methods
Return a new instance of whatever object type will be used to represent the subject.