lokap-presenter 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1309d832f67f5f6647903f2cf3a98a2c7e8ab5335229faa243cd54bd9cbbc977
4
+ data.tar.gz: 114a5bd96c592e832664df4c60749943fbfa9ae47f944d5b812913210c69a73f
5
+ SHA512:
6
+ metadata.gz: 2afa4a16cfccd59e8f250488123a15c801b3fda63fb6675510e92f056da514104f3801a20feb67be681d53b15397f3fcc2e948d7a769005e1f236668e5ef28e6
7
+ data.tar.gz: a4ae06040ad7ac85a795fb41e929b8fd4b50ca5fc2db84a79280262c172f704c78ebe2990b16ade950ffdfc665a28a6d52babb720fc71c8e20cbcc942c1f25f9
data/.yardopts ADDED
@@ -0,0 +1,5 @@
1
+ --private
2
+ --markup-provider=redcarpet
3
+ --markup=markdown
4
+ -
5
+ CHANGELOG.md
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## [0.0.1] - 2022-07-01
2
+
3
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+ gemspec
5
+
6
+ gem "rake", "~> 13.0"
7
+ gem "minitest", "~> 5.0"
8
+ gem "yard"
9
+ gem "redcarpet"
10
+ gem "github-markup"
11
+
data/Gemfile.lock ADDED
@@ -0,0 +1,29 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ lokap-presenter (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ github-markup (4.0.1)
10
+ minitest (5.15.0)
11
+ rake (13.0.6)
12
+ redcarpet (3.5.1)
13
+ webrick (1.7.0)
14
+ yard (0.9.28)
15
+ webrick (~> 1.7.0)
16
+
17
+ PLATFORMS
18
+ arm64-darwin-21
19
+
20
+ DEPENDENCIES
21
+ github-markup
22
+ lokap-presenter!
23
+ minitest (~> 5.0)
24
+ rake (~> 13.0)
25
+ redcarpet
26
+ yard
27
+
28
+ BUNDLED WITH
29
+ 2.3.14
data/README.md ADDED
@@ -0,0 +1,123 @@
1
+ A simple Rails view presenter for those with discerning taste.
2
+ _From the Library of Knowledge and Power_
3
+
4
+ ## Installation
5
+
6
+ Add this line to your application's Gemfile:
7
+
8
+ ```ruby
9
+ gem 'lokap-presenter'
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ Call the presenter within your view using the `present` helper:
15
+
16
+ ```ruby
17
+ present(object, :class_name).render('template')
18
+ ```
19
+
20
+ Your Presenter will be searched for in:
21
+
22
+ ```
23
+ app/presenters/<class_name>_presenter.rb
24
+ ```
25
+
26
+ Templates will be searched for in:
27
+
28
+ ```
29
+ app/views/presenters/<class_name>/_default.html.erb
30
+ app/views/presenters/<class_name>/_<template>.html.erb
31
+ ```
32
+
33
+ And can be used like so:
34
+
35
+ ```ruby
36
+ present(@person, :emotion).render
37
+ # => app/presenters/emotion_presenter.rb
38
+ # => app/views/presenters/emotion/_default.html.erb
39
+
40
+ present(@person, :emotion).render(:happy)
41
+ # => app/presenters/emotion_presenter.rb
42
+ # => app/views/presenters/emotion/_happy.html.erb
43
+
44
+ present(@person, :emotion).render(:sad)
45
+ # => app/presenters/emotion_presenter.rb
46
+ # => app/views/presenters/emotion/_sad.html.erb
47
+ ```
48
+
49
+ Access the presenter inside your presenter templates:
50
+
51
+ ```ruby
52
+ presenter.show_emotion
53
+ p.show_emotion
54
+ ```
55
+
56
+ ### The Presenter Class
57
+
58
+ The class has full access to the view... and view helpers, etc.
59
+ _Think of this as a helper on steroids (but less angry)_
60
+
61
+ ```ruby
62
+ class EmotionPresenter < Lokap::Presenter
63
+ presents :person
64
+ delegate :emotions, :moods, to: :human
65
+
66
+ def who_is_this
67
+ person
68
+ end
69
+
70
+ def show_emotion
71
+ emotions.logic
72
+ end
73
+
74
+ def show_mood
75
+ moods.logic
76
+ end
77
+ end
78
+ ```
79
+
80
+ ### Default Templates
81
+
82
+ If a specified template is not found, the presenter will attempt to render a
83
+ default view.
84
+
85
+ ```ruby
86
+ present(@person, :share).render(:twitter)
87
+
88
+ # looks for /views/presenters/share/_twitter.html.erb (doesn't exist)
89
+ # => /views/presenters/share/_default.html.erb
90
+ ```
91
+
92
+ This will also work for templates inside subfolders:
93
+
94
+ ```ruby
95
+ present(@person, :share).render('social/twitter')
96
+
97
+ # looks for /views/presenters/share/social/_twitter.html.erb (doesn't exist)
98
+ # => /views/presenters/share/social/_default.html.erb
99
+ ```
100
+
101
+ ## Examples
102
+
103
+ Here are a few different ways to utilize presenters:
104
+
105
+ ```ruby
106
+ # Render (Default)
107
+ present(@person, :share).render
108
+ present(@person, :share).render(:twitter)
109
+ present(@person, :share).render('social/twitter')
110
+
111
+ # Block
112
+ present(@person, :share) do |p|
113
+ link_to p.text, p.url
114
+ end
115
+
116
+ # Object
117
+ share = present(@person, :share)
118
+ share.render(:twitter)
119
+ share.render(:facebook)
120
+ share.render(:email)
121
+ ```
122
+
123
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << "test"
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/**/test_*.rb"]
10
+ end
11
+
12
+ task default: :test
@@ -0,0 +1,29 @@
1
+ module Lokap
2
+ module ActionView
3
+ # Raised when `ActionView::Context` can't locate a presenter's template
4
+ # _(We catch the error and attempt to render a default template)_
5
+ class MissingTemplate < ::ActionView::MissingTemplate; end
6
+
7
+ # Helper method which allows access to your presenters
8
+ #
9
+ # @example
10
+ # present(@person, :share).render
11
+ # present(@person, :share).render(:twitter)
12
+ # present(@person, :share).render('social/twitter')
13
+ #
14
+ # @param entity [Object] The object to present
15
+ # @param klass [Object] The underscored class name of your presenter
16
+ # @param options [Hash] Passed to the presenter (and template)
17
+ #
18
+ # @return [Lokap::Presenter] an instance of your presenter
19
+ def present(entity, klass = nil, options={})
20
+ base_klass = klass ? klass.to_s.titleize.gsub(' ', '') : entity.class
21
+ klass = "#{base_klass}Presenter".constantize
22
+ presenter = klass.new(entity, self, options)
23
+ yield presenter and return if block_given?
24
+ presenter
25
+ end
26
+ end
27
+ end
28
+
29
+ ActionView::Base.send(:include, Lokap::ActionView)
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ if defined?(ActiveSupport.on_load)
4
+ ActiveSupport.on_load(:action_view) do
5
+ require_relative 'presenter/ext/action_view'
6
+ end
7
+ end
8
+
9
+ module Lokap
10
+ #
11
+ # `Lokap::Presenter` is the base class for which all presenters inherit
12
+ #
13
+ # @attribute context
14
+ # @return [ActionView] Rails view context
15
+ # @attribute options
16
+ # @return [Hash] Options passed to the presenter and the template
17
+ #
18
+ class Presenter < SimpleDelegator
19
+ attr_reader :context
20
+ attr_accessor :options
21
+
22
+ # Creates a new `Lokap::Presenter` object
23
+ # @see Lokap::ActionView#present
24
+ #
25
+ # @example
26
+ # present(@person, :share).render
27
+ # present(@person, :share).render(:twitter)
28
+ # present(@person, :share).render('social/twitter')
29
+ #
30
+ # @param entity [Object] Object/entity to present
31
+ # @param context [ActionView::Context] Rails view context for rendering
32
+ # @param options [Hash] Options passed to the presenter and template
33
+ #
34
+ # @return [Lokap::Presenter]
35
+ def initialize(entity, context, options={})
36
+ @entity = entity
37
+ @context = context
38
+ @options = options
39
+
40
+ super(@context)
41
+ end
42
+
43
+ # Renders the specified template for a presenter
44
+ # @param partial [String|Symbol] The name of the partial in `app/views/presenters`
45
+ # @return [String] HTML output
46
+ def render(partial=nil)
47
+ super partial_options(partial)
48
+ rescue Lokap::ActionView::MissingTemplate
49
+ super partial_options(default_path(partial))
50
+ end
51
+
52
+ private
53
+
54
+ # Defines a method to access the presented entity
55
+ # @param name [String|Symbol] Name of the entity
56
+ def self.presents(name)
57
+ define_method(name) { @entity }
58
+ end
59
+
60
+ # Makes the presenter available to it's templates via `p.<method>` or
61
+ # `presenter.<method>`
62
+ def locals
63
+ { presenter: self, p: self }.merge(options)
64
+ end
65
+
66
+ # Generate Hash options to pass to the renderer
67
+ # @param partial [String] path to the template's partial
68
+ # @return [Hash] These options are passed to `render :partial, <options>`
69
+ def partial_options(partial=nil)
70
+ {
71
+ partial: template_path(partial),
72
+ locals: locals
73
+ }
74
+ end
75
+
76
+ # The full path of the template to be rendered
77
+ # @param partial [String] The name of the partial to render
78
+ # @return [String] Full path to the template's partial
79
+ def template_path(partial=nil)
80
+ template = partial || default_template
81
+ "/presenters/#{class_path}/#{template}".downcase
82
+ end
83
+
84
+ # Generates the name for the class segment of the path
85
+ # @note Removes `_presenter` from the resulting string if present
86
+ # @return [String] Path for the subclassed presenter
87
+ def class_path
88
+ self.class.name.underscore.gsub('_presenter', '')
89
+ end
90
+
91
+ # Generates the default partial path when a template is not found or specified
92
+ # @param partial [String] full path to the template's partial
93
+ # @returns [String] full path to the specified template or the default template
94
+ def default_path(partial=nil)
95
+ return unless partial
96
+ prefix = partial.to_s.split('/')[0..-2].join('/')
97
+ [prefix, default_template].compact.join('/')
98
+ end
99
+
100
+ # The default name for the template when specified template can't be found
101
+ def default_template
102
+ 'default'
103
+ end
104
+ end
105
+ end
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lokap-presenter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Adam Bair
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-07-07 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - adambair@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".yardopts"
21
+ - CHANGELOG.md
22
+ - Gemfile
23
+ - Gemfile.lock
24
+ - README.md
25
+ - Rakefile
26
+ - lib/lokap/presenter.rb
27
+ - lib/lokap/presenter/ext/action_view.rb
28
+ homepage: https://github.com/adambair/lokap-presenter
29
+ licenses:
30
+ - Nonstandard
31
+ metadata:
32
+ allowed_push_host: https://rubygems.org/
33
+ homepage_uri: https://github.com/adambair/lokap-presenter
34
+ source_code_uri: https://github.com/adambair/lokap-presenter
35
+ changelog_uri: https://github.com/adambair/lokap-presenter
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 2.6.0
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubygems_version: 3.3.14
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: A view presenter for those with discerning taste
55
+ test_files: []