Last active
January 12, 2018 05:16
-
-
Save elskwid/fcb7a1cec5e26eb7e697d43fe0182899 to your computer and use it in GitHub Desktop.
Simple Rails Presenter and View Presenter (so I don't forget)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
module Foo | |
# Simple presenter module | |
# | |
# Uses Charlatan to create an `Foo::Presenter` module for use in the app. | |
# This isn't *strictly* a presenter - it's somewhere between a presenter, | |
# proxy, and/or decorator. | |
# | |
# Including `Foo::Presenter.new(:presented_thing)` in a class will | |
# create a module (Charlatan inherits from Module) that, in turn, creates | |
# an initializer so the proxied object is stored in the instance and | |
# available through an instance method. | |
# | |
# Example: | |
# class MyPresenter | |
# include Foo::Presenter.new(:array) | |
# | |
# def second_item | |
# array.second | |
# end | |
# end | |
# | |
# array = [1, 2, 3] | |
# my_presenter = MyPresenter.new(array) | |
# | |
# # available at the instance method | |
# my_presenter.array | |
# #=> [1, 2, 3] | |
# | |
# # presenter appears *to be* the array | |
# my_presenter.length | |
# #=> 3 | |
# | |
# # can decorate with new methods | |
# my_presenter.second_item | |
# #=> 2 | |
class Presenter < Charlatan | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
module Foo | |
# Simple presenter for view-related uses that mixes in some useful Rails | |
# view helpers. | |
# | |
# Of note, the view presenter includes the Rails URL helpers so things like | |
# `link_to` and `url_for` work. These are tricky helpers that require a few | |
# dependencies and they have a very specific load order. | |
# | |
# See example in Foo::Presenter | |
class ViewPresenter < Presenter | |
def initialize(*args) | |
super # let Charlatan do its thing | |
include ActionView::Helpers::DateHelper | |
include ActionView::Helpers::NumberHelper | |
include ActionView::Helpers::SanitizeHelper | |
include ActionView::Helpers::TextHelper | |
include ActionView::Helpers::TranslationHelper | |
include ActionView::Helpers::UrlHelper | |
include InlineSvg::ActionView::Helpers | |
include ApplicationHelper # bring in our global helpers | |
end | |
def included(mod) | |
mod.extend ClassMethods | |
mod.extend Sanitizers | |
mod.include InstanceMethods | |
mod.include Rails.application.routes.url_helpers | |
end | |
# Class methods(s) needed by various helpers | |
module ClassMethods | |
# Delegate the default urls options to ActionMailer | |
def default_url_options | |
ActionMailer::Base.default_url_options.merge( | |
protocol: Rails.env.in?(%w[test development]) ? "http" : "https" | |
) | |
end | |
def present_each(collection, *args, **kwargs) | |
return unless collection.respond_to?(:map) | |
collection.map { |item| new(item, *args, **kwargs) } | |
end | |
end | |
# Instance method(s) needed by various helpers | |
module InstanceMethods | |
def present_collection(collection:, presenter:) | |
collection.map { |item| presenter.new(item) } | |
end | |
# url helpers require options and default options or they override | |
def url_options | |
self.class.default_url_options | |
end | |
alias default_url_options url_options | |
# return the value or a default | |
def value_or_default(value, default = nil) | |
value.present? ? value : default | |
end | |
end | |
end | |
# Sanitizer methods required by `SanitizeHelper` | |
module Sanitizers | |
def full_sanitizer | |
@full_sanitizer ||= Rails::Html::FullSanitizer.new | |
end | |
def link_sanitizer | |
@link_sanitizer ||= Rails::Html::LinkSanitizer.new | |
end | |
def white_list_sanitizer | |
@white_list_sanitizer ||= Rails::Html::WhiteListSanitizer.new | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment