magic-presenter 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 17e4d44c0c2d9a9e09e7e099a4067b9e6aafe27e1b389cf01808ed0a77d0b9ae
4
- data.tar.gz: 7d492486c2f4edb2407af461794e1f0c7e53c7f6b93e65595a618369fb845250
3
+ metadata.gz: 8ca84b456b21332f6eeba63a5667ed1c8cf7ac97d59141192f138d1698c504bf
4
+ data.tar.gz: c380ea14f2ddd44150ae71095063e895486d33077521fe1067fca81d4c4b36b0
5
5
  SHA512:
6
- metadata.gz: fb2609c3dbba1cec025bca22aaa196c718b32084b2954b8184f9b5ce896e7a9289c0b7eb0660469edaf3571d27d99026f6e588f58004e395cee07a75820e38d7
7
- data.tar.gz: 1a87908713cb7dbcb029687dd1d4b9006432e8ba9703ef1dbe813088060c471ada70f8d7d1f5de4cdc9210ba602bd0457b1bf061f6fd3d9a25c5a420003198e0
6
+ metadata.gz: 728dbf1b11115069bb58bfb47c81258f358d22c3570c35dc4a5e7e4d9429a2fa5a6dc3237d0ef0e6a0442d88ca7e9b405e481bd5ea2da90c618800593c8f5155
7
+ data.tar.gz: f014751ea9cf0470fd1387f25f63b56291a63a434abd177ca0e1aaab27ba1d9a4da4e590354b729fcd12a40fa19f125866daedfba4bd904f37e8d48b3c281ea6
data/README.md CHANGED
@@ -68,6 +68,35 @@ See the help for more info:
68
68
 
69
69
  $ bin/rails generate presenter --help
70
70
 
71
+ ### View helpers
72
+
73
+ A presenter can use any helpers via `#helpers` (aliased as `#h`) both in class and instance methods:
74
+
75
+ ```ruby
76
+ class PersonPresenter < Magic::Presenter::Base
77
+ def self.links
78
+ [ h.link_to('All', model_class) ]
79
+ end
80
+
81
+ def link(...)
82
+ helpers.link_to(name, self, ...)
83
+ end
84
+ end
85
+ ```
86
+
87
+ A view context must be set to enable helpers.
88
+ It’s done automagically [wherever possible](#helpers).
89
+ However, one can set it explicitly anywhere:
90
+
91
+ ```ruby
92
+ Magic::Presenter.with view_context: ApplicationController.new.view_context do
93
+ # put the code that uses helpers within presenters here
94
+ end
95
+ ```
96
+
97
+ > [!NOTE]
98
+ > A valid `request` may be needed for URL helpers to get host info.
99
+
71
100
  ## 🧙 Magic
72
101
 
73
102
  It’s based on [Magic Decorator](
@@ -109,6 +138,13 @@ Magic::Presenter.name_for Person # => "PersonPresenter"
109
138
  > Every object passed to views is decorated automagically.
110
139
  > This involves both implicit instance variables and `locals` passed explicitly.
111
140
 
141
+ ### Helpers
142
+
143
+ View context is set automagically to enable helpers:
144
+ - in views,
145
+ - in controller actions,
146
+ - in mailer actions.
147
+
112
148
  ## Development
113
149
 
114
150
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ presenter_context = proc do
4
+ around_action :set_presenter_context
5
+
6
+ private
7
+
8
+ def set_presenter_context(&)
9
+ Magic::Presenter.with view_context:, &
10
+ end
11
+ end
12
+
13
+ ActiveSupport.on_load :action_controller, &presenter_context
14
+ ActiveSupport.on_load :action_mailer, &presenter_context
@@ -1,19 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ActiveSupport.on_load :action_view do
3
+ ActiveSupport.on_load :action_view do # rubocop:disable Metrics/BlockLength
4
4
  concerning :DecoratedAssignments, prepend: true do
5
5
  def assign(assignments, ...)
6
- assignments
7
- .transform_values! &:decorated
6
+ decorate assignments
8
7
 
9
8
  super
10
9
  end
11
10
 
12
11
  def _run(method, template, locals, ...)
13
- locals
14
- .transform_values! &:decorated
12
+ decorate locals
15
13
 
16
14
  super
17
15
  end
16
+
17
+ private
18
+
19
+ def decorate objects
20
+ objects
21
+ .transform_values!(&:decorated)
22
+ end
23
+ end
24
+
25
+ concerning :PresenterContext, prepend: true do
26
+ def in_rendering_context(...)
27
+ Magic::Presenter::Base.with view_context: self do
28
+ super
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def decorate(...)
35
+ super
36
+ .each_value
37
+ .grep(Magic::Presenter::Base)
38
+ .each { _1.view_context = self }
39
+ end
18
40
  end
19
41
  end
@@ -18,6 +18,7 @@ module Magic
18
18
  # up to `ObjectPresenter`.
19
19
  class Base < Decorator::Base
20
20
  include GlobalID if defined? ::GlobalID
21
+ prepend Helpers if defined? ::ActionView
21
22
 
22
23
  class << self
23
24
  def name_for object_class
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Magic
4
+ module Presenter
5
+ module Helpers # :nodoc:
6
+ extend ActiveSupport::Concern
7
+
8
+ # The Magic::Presenter::Helpers::MissingContext exception is
9
+ # raised when no view context to run helpers in has been set.
10
+ class MissingContext < RuntimeError
11
+ def message
12
+ <<~TEXT
13
+ missing view context
14
+ You should set Magic::Presenter.view_context first
15
+ TEXT
16
+ end
17
+ end
18
+
19
+ prepended do
20
+ class_attribute :view_context
21
+ end
22
+
23
+ class_methods do
24
+ include Helpers
25
+
26
+ alias __raise__ raise
27
+ end
28
+
29
+ private
30
+
31
+ def helpers
32
+ view_context or
33
+ __raise__ MissingContext
34
+ end
35
+
36
+ alias_method :h, :helpers
37
+
38
+ def method_missing(method, ...)
39
+ super
40
+ rescue NoMethodError
41
+ __raise__ unless view_context
42
+ __raise__ unless helpers.respond_to? method
43
+
44
+ helpers.send(method, ...)
45
+ end
46
+
47
+ def respond_to_missing?(method, ...)
48
+ super or
49
+ (helpers if view_context).respond_to?(method, ...)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Magic
4
4
  module Presenter
5
- VERSION = '0.3.0'
5
+ VERSION = '0.4.0'
6
6
  end
7
7
  end
@@ -9,13 +9,14 @@ module Magic # :nodoc:
9
9
  # Presentation layer for Rails models
10
10
  module Presenter
11
11
  autoload :Base, 'magic/presenter/base'
12
+ autoload :Helpers, 'magic/presenter/helpers'
12
13
  autoload :GlobalID, 'magic/presenter/global_id'
13
14
  autoload :Generator, 'generators/magic/presenter/generator'
14
15
 
15
- module_function
16
-
17
- def for(...) = Base.for(...)
18
- def name_for(...) = Base.name_for(...)
16
+ singleton_class.delegate *%i[
17
+ for name_for
18
+ view_context view_context=
19
+ ], to: Base
19
20
  end
20
21
 
21
22
  module_function
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magic-presenter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Senko
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2024-10-27 00:00:00.000000000 Z
10
+ date: 2024-10-29 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: rails
@@ -54,6 +54,7 @@ files:
54
54
  - README.md
55
55
  - Rakefile
56
56
  - app/models/concerns/magic/presentable.rb
57
+ - config/initializers/action_controller.rb
57
58
  - config/initializers/action_view.rb
58
59
  - config/initializers/presentable.rb
59
60
  - config/initializers/rspec.rb
@@ -73,6 +74,7 @@ files:
73
74
  - lib/magic/presenter/base.rb
74
75
  - lib/magic/presenter/engine.rb
75
76
  - lib/magic/presenter/global_id.rb
77
+ - lib/magic/presenter/helpers.rb
76
78
  - lib/magic/presenter/version.rb
77
79
  - lib/tasks/magic/presenter_tasks.rake
78
80
  homepage: https://github.com/Alexander-Senko/magic-presenter
@@ -81,7 +83,7 @@ licenses:
81
83
  metadata:
82
84
  homepage_uri: https://github.com/Alexander-Senko/magic-presenter
83
85
  source_code_uri: https://github.com/Alexander-Senko/magic-presenter
84
- changelog_uri: https://github.com/Alexander-Senko/magic-presenter/blob/v0.3.0/CHANGELOG.md
86
+ changelog_uri: https://github.com/Alexander-Senko/magic-presenter/blob/v0.4.0/CHANGELOG.md
85
87
  rdoc_options: []
86
88
  require_paths:
87
89
  - lib