roda-phlex 0.1.0 → 0.3.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: 697b0c167a1b8e7c0a878d07a7b45c69e8ce1ea4ec7d04a8a2a1743df8856d63
4
- data.tar.gz: 0ef55428df093f8e8d61106b7819bf822fea490228e58c7c921ecf8e4d54aed6
3
+ metadata.gz: 1012a871d2413c575d0807b04cfc92d9c39bbddc82b3a5769c398a82a1868951
4
+ data.tar.gz: 371dac4531e28280836ad52dcb623ef4fef01b7331c2a1a364c9f58fc0b598b8
5
5
  SHA512:
6
- metadata.gz: 6789258cef5d8ed114bc9cf5322b3440eb5b01122a8d046f09f30fe0382ee3b2eb7a2f055089c25cbce2d351d4b7da1041691e5c03a272c439b4fd41ad8440c7
7
- data.tar.gz: c98632f1b504f435755b410dfcf0a5c7cc61b2f8fd9e59048bcde01966b01749b04a8aef1c4557a3f50e38911580e014a3869fe2a41408b2516e76ac55007ccf
6
+ metadata.gz: 0a1221224003fa28b9ea5d73eccd8a93d60d0186d01dd05f2c28947cabfc3b7c1d7b1349159b2778777fe03af25affa4643780505a1b197ec80e9741ae191460
7
+ data.tar.gz: c044bf1340e4c95bd72d37c64f1f5af3a183950237b8884d451be51a74e3792eb4fc3a7c6b107779eacaec6e4ce0dd4570aaed7fb075a89664ffa3087ef8cd22
data/.markdownlint.yml ADDED
@@ -0,0 +1,10 @@
1
+ MD004: # Unordered list style
2
+ style: sublist
3
+ MD007: # Unordered list indentation
4
+ indent: 4 # For Yard
5
+ MD013: # Line length
6
+ line_length: 120
7
+ code_blocks: false
8
+ tables: false
9
+ MD024: # Multiple headers with the same content
10
+ siblings_only: true
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
1
  --format documentation
2
2
  --color
3
3
  --require spec_helper
4
+ --tag ~isolate
data/.yardopts ADDED
@@ -0,0 +1,2 @@
1
+ -m markdown
2
+ --files LICENSE.txt,CHANGELOG.md
data/CHANGELOG.md CHANGED
@@ -1,5 +1,94 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
6
+
1
7
  ## [Unreleased]
2
8
 
9
+ ### Added
10
+
11
+ ### Changed
12
+
13
+ ### Deprecated
14
+
15
+ ### Removed
16
+
17
+ ### Fixed
18
+
19
+ ### Security
20
+
21
+ ## [0.3.0] - 2025-01-27
22
+
23
+ ### Added
24
+
25
+ - Support for Phlex Component context. (`HelloWorld.new.call(context: {some: :data})`).
26
+ + Like layout options, the `:context` plugin option can be used to set a default context.
27
+ The value will be`dup`ed on first use.
28
+ + `#phlex_context` method to access the context.
29
+ + `#set_phlex_context` method to set the context.
30
+ - `:delegate_on` plugin option to specify the object to delegate methods to.
31
+ Defaults to `::Phlex::SGML` but its advised to set it to your own subclass of `::Phlex::SGML`.
32
+ - `:delegate_name` plugin option to specify name of the method that delegates to the Roda app.
33
+ Defaults to `"app"`.
34
+
35
+ ### Changed
36
+
37
+ - `#phlex_layout`, `#phlex_layout_opts`, `#phlex_layout_handler` no longer accept a value to set their value.
38
+ Use their corresponding `#set_*` methods instead.
39
+
40
+ ### Removed
41
+
42
+ - `delegate: :all` plugin option removed. You need to specify the methods to delegate explicitly.
43
+ - `delegate: <Symbol,String>` plugin option removed. Method names need to be specified as an array of
44
+ symbols or strings, even when delegating only one method.
45
+
46
+ ### Fixed
47
+
48
+ - Mutating the layout options hash no longer affects subsequent requests.
49
+ The value passed as `:layout_opts` plugin config is now `dup`ed on first use.
50
+ Note, that mutating nested objects will still affect the original hash.
51
+
52
+ ## [0.2.0] - 2024-12-13
53
+
54
+ ### Added
55
+
56
+ - Allow `phlex_layout(false)` to be used to reset disable layout.
57
+ - Allow `phlex_layout_handler(:default)` to be used to reset to the default layout handler.
58
+
59
+ ### Removed
60
+
61
+ - Don't delete layout options when deleting layout (eg via `phlex_layout(false)`)
62
+
63
+ ### Fixed
64
+
65
+ - `phlex_layout` should accept a `Phlex::SGML` class, not instance.
66
+ - `phlex_layout_handler` called with `nil` resets it to the default handler.
67
+
3
68
  ## [0.1.0] - 2024-08-28
4
69
 
5
- - Initial release based on <https://github.com/benpickles/phlex-sinatra/commit/2e3c9a612cbf6f4b4bf5db880f164b66f008baf8> and <https://gist.github.com/RomanTurner/0ce0b8792e4149d152d2af2224cb6407>
70
+ - Initial release based on <https://github.com/benpickles/phlex-sinatra/commit/2e3c9a612cbf6f4b4bf5db880f164b66f008baf8>
71
+ and <https://gist.github.com/RomanTurner/0ce0b8792e4149d152d2af2224cb6407>
72
+
73
+ ________________________________________________________________________________
74
+
75
+ [Unreleased]: https://github.com/fnordfish/roda-phlex/compare/v0.3.0...phlex-1
76
+ [0.3.0]: https://github.com/fnordfish/roda-phlex/releases/tag/v0.3.0
77
+ [0.2.0]: https://github.com/fnordfish/roda-phlex/releases/tag/v0.2.0
78
+ [0.1.0]: https://github.com/fnordfish/roda-phlex/releases/tag/v0.1.0
79
+
80
+ <!-- template for new release:
81
+ ### Added
82
+
83
+ ### Changed
84
+
85
+ ### Deprecated
86
+
87
+ ### Removed
88
+
89
+ ### Fixed
90
+
91
+ ### Security
92
+
93
+ ## [X.Y.Z] - YYYY-MM-DD
94
+ -->
data/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # roda-phlex
2
2
 
3
- A [Roda](https://github.com/jeremyevans/roda) plugin that adds some convenience rendering [Phlex](https://github.com/phlex-ruby/phlex) views.
3
+ A [Roda](https://github.com/jeremyevans/roda) plugin that adds some convenience rendering
4
+ [Phlex](https://github.com/phlex-ruby/phlex) views.
4
5
  Especially accessing application methods from the view.
5
6
 
7
+ * API documentation is available at [https://www.rubydoc.info/gems/roda-phlex](https://www.rubydoc.info/gems/roda-phlex/Roda/RodaPlugins/Phlex/InstanceMethods)
8
+
6
9
  ## Installation
7
10
 
8
11
  Install the gem and add to the application's Gemfile by executing:
@@ -21,23 +24,30 @@ gem install roda-phlex
21
24
 
22
25
  `plugin :phlex` takes the following options:
23
26
 
24
- - `:layout` (`Phlex::SGML`): Specifies the layout class to be used for rendering
27
+ * `:layout` (`Phlex::SGML`): Specifies the layout class to be used for rendering
25
28
  views. This class should be a Phlex layout class that defines how the
26
29
  views are structured and rendered.
27
- - `:layout_opts` (`Object`): Options that are passed to the layout
30
+ * `:layout_opts` (`Object`): Options that are passed to the layout
28
31
  class when it is instantiated. These options can be used to customize
29
32
  the behavior of the layout. Usually, this is a `Hash`.
30
- - `:layout_handler` (`#call`): A custom handler for creating layout
33
+ To avoid external changes effecting subsequent requests, you should `.freeze` this
34
+ and all nested objects.
35
+ * `:layout_handler` (`#call`): A custom handler for creating layout
31
36
  instances. This proc receives three arguments: the layout class, the
32
- layout options, and the object to be rendered. By default, it uses the
37
+ layout options, and the object to be rendered. By default, it runs
33
38
  `layout.new(obj, **layout_opts)`, which instantiates the layout class with the
34
39
  provided view object and options as keyword arguments.
35
- - `:delegate`: Define if or which methods should be delegated to the Roda app:
36
- - `true` (default): Create a single `app` method that delegates to the Roda app.
37
- - `false`: Do not create any delegate methods.
38
- - `:all`: Delegate all methods the Roda app responds to, to it. Be careful with this option.
39
- It can lead to unexpected behavior if the Roda app has methods that conflict with Phlex methods.
40
- - `Symbol`, `String`, `Array`: Delegate only the specified methods to the Roda app.
40
+ * `:context` (`Hash`): The context that is passed to the rendering call. (default: `{}`)
41
+ To avoid external changes effecting subsequent requests, you should `.freeze` this
42
+ and all nested objects.
43
+ * `:delegate`: Define if or which methods should be delegated to the Roda app:
44
+ + `true` (default): Create a single `app` method that delegates to the Roda app.
45
+ + `false`: Do not create any delegate methods.
46
+ + `Array<Symbol,String>`: Delegate the named methods to the Roda app.
47
+ * `:delegate_on`: Class or module to define delegation methods on. Defaults to `::Phlex::SGML`.
48
+ + Use this option to limit delegation methods to a application specific class or module
49
+ (like "ApplicationView") to avoid polluting the global namespace.
50
+ * `:delegate_name`: The name of the method that delegates to the Roda app. Defaults to `"app"`.
41
51
 
42
52
  ## Usage
43
53
 
@@ -86,7 +96,8 @@ end
86
96
 
87
97
  ## Streaming
88
98
 
89
- Streaming a Phlex view can be enabled by passing `stream: true` which will cause Phlex to automatically write to the response after the closing `</head>` and buffer the remaining content.
99
+ Streaming a Phlex view can be enabled by passing `stream: true` which will cause Phlex to automatically write
100
+ to the response after the closing `</head>` and buffer the remaining content.
90
101
  The Roda `:stream` plugin must be enabled for this to work.
91
102
 
92
103
  ```ruby
@@ -101,7 +112,7 @@ You can also manually flush the contents of the buffer at any point using Phlex'
101
112
 
102
113
  ```ruby
103
114
  class Layout < Phlex::HTML
104
- def template(&block)
115
+ def view_template(&block)
105
116
  doctype
106
117
  html {
107
118
  head {
@@ -113,14 +124,14 @@ class Layout < Phlex::HTML
113
124
  # Standard site header and navigation.
114
125
  render Header.new
115
126
 
116
- yield_content(&block)
127
+ yield
117
128
  }
118
129
  }
119
130
  end
120
131
  end
121
132
 
122
133
  class MyView < Phlex::HTML
123
- def template
134
+ def view_template
124
135
  render Layout.new {
125
136
  # Knowing that this page can take a while to generate we can choose to
126
137
  # flush here so the browser can render the site header while downloading
@@ -138,16 +149,17 @@ end
138
149
 
139
150
  ```ruby
140
151
  # Define a default layout and layout options for the whole application
141
- plugin :phlex, layout: MyLayout, layout_opts: { title: +"My App" }
152
+ plugin :phlex, layout: MyLayout, layout_opts: { title: "My App".freeze }.freeze
153
+
142
154
  route do |r|
143
155
  r.on "posts" do
144
156
  # redefine the layout and layout options for this route tree
145
- phlex_layout MyPostLayout
146
- phlex_layout_opts[:title] << " - Posts"
157
+ set_phlex_layout MyPostLayout
158
+ set_phlex_layout_opts phlex_layout_opts.merge(title: "#{phlex_layout_opts[:title]} - Posts")
147
159
 
148
160
  r.get 'new' do
149
161
  # Redefine the layout and layout options for this route
150
- phlex_layout_opts[:title] = "Create new post"
162
+ phlex_layout_opts[:title] << " - Create new post"
151
163
  phlex MyView.new
152
164
  end
153
165
  end
@@ -156,7 +168,9 @@ end
156
168
 
157
169
  ## Contributing
158
170
 
159
- Bug reports and pull requests are welcome on GitHub at <https://github.com/fnordfish/roda-phlex>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/fnordfish/roda-phlex/blob/main/CODE_OF_CONDUCT.md).
171
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/fnordfish/roda-phlex>.
172
+ This project is intended to be a safe, welcoming space for collaboration, and contributors are expected
173
+ to adhere to the [code of conduct](https://github.com/fnordfish/roda-phlex/blob/main/CODE_OF_CONDUCT.md).
160
174
 
161
175
  ## License
162
176
 
@@ -164,8 +178,10 @@ The gem is available as open source under the terms of the [MIT License](https:/
164
178
 
165
179
  ## Code of Conduct
166
180
 
167
- Everyone interacting in the Roda::Phlex project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/fnordfish/roda-phlex/blob/main/CODE_OF_CONDUCT.md).
181
+ Everyone interacting in the Roda::Phlex project's codebases, issue trackers, chat rooms and mailing lists is expected
182
+ to follow the [code of conduct](https://github.com/fnordfish/roda-phlex/blob/main/CODE_OF_CONDUCT.md).
168
183
 
169
184
  ## Acknowledgements
170
185
 
171
- This gem is based on [phlex-sinatra](https://github.com/benpickles/phlex-sinatra), and extended by the layout handling features in [RomanTurner's gist](https://gist.github.com/RomanTurner/0ce0b8792e4149d152d2af2224cb6407)
186
+ This gem is based on [phlex-sinatra](https://github.com/benpickles/phlex-sinatra), and extended by the layout handling
187
+ features in [RomanTurner's gist](https://gist.github.com/RomanTurner/0ce0b8792e4149d152d2af2224cb6407)
data/Rakefile CHANGED
@@ -7,4 +7,9 @@ RSpec::Core::RakeTask.new(:spec)
7
7
 
8
8
  require "standard/rake"
9
9
 
10
+ Rake::Task["spec"].enhance do
11
+ sh "bundle", "exec", "rspec", "-t", "isolate", "spec/roda/delegation_error_spec.rb"
12
+ sh "bundle", "exec", "rspec", "-t", "isolate", "spec/roda/delegation_spec.rb"
13
+ end
14
+
10
15
  task default: %i[spec standard]
data/lib/roda/phlex.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  class Roda
4
4
  module RodaPlugins
5
5
  module Phlex
6
- VERSION = "0.1.0"
6
+ VERSION = "0.3.0"
7
7
  end
8
8
  end
9
9
  end
@@ -17,16 +17,16 @@ class Roda
17
17
  # layout options, and the object to be rendered. By default, it uses the
18
18
  # `DEFAULT_LAYOUT_HANDLER`, which instantiates the layout class with the
19
19
  # provided object and options as keyword arguments.
20
+ # - `:context` (+Hash+): The context that is passed to the rendering call. (default: `{}`)
20
21
  # - `:delegate`: Define if or which methods should be delegated to the Roda app:
21
- # - `true` (default): Create a single `app` method that delegates to the Roda app.
22
- # - `false`: Do not create any delegate methods.
23
- # - `:all`: Delegate all methods the Roda app responds to, to it. Be careful with this option.
24
- # It can lead to unexpected behavior if the Roda app has methods that conflict with Phlex methods.
25
- # - `Symbol`, `String`, `Array`: Delegate only the specified methods to the Roda app.
22
+ # + `true` (default): Create a single `app` method that delegates to the Roda app.
23
+ # + `false`: Do not create any delegate methods.
24
+ # + `Array<Symbol,String>`: Delegate the named methods to the Roda app.
25
+ # - `:delegate_on`: Class or module to define delegation methods on. Defaults to +::Phlex::SGML+.
26
+ # + Use this option to limit delegation methods to a application specific class or module
27
+ # (like "ApplicationView") to avoid polluting the global namespace.
28
+ # - `:delegate_name`: The name of the method that delegates to the Roda app. Defaults to `"app"`.
26
29
  module Phlex
27
- Undefined = Object.new
28
- private_constant :Undefined
29
-
30
30
  Error = Class.new(StandardError)
31
31
 
32
32
  # Custom TypeError class for Phlex errors.
@@ -44,122 +44,172 @@ class Roda
44
44
 
45
45
  # The default layout handler for creating layout instances.
46
46
  # Expects layout options to be a +Hash+ when provided.
47
+ # Layout options are passed as keyword arguments to the layout class.
48
+ #
49
+ # @param layout [Class] The layout class to be instantiated.
50
+ # @param layout_opts [Hash, nil] The layout options to be passed to the layout class.
51
+ # @param obj [Phlex::SGML] The object to be rendered.
47
52
  DEFAULT_LAYOUT_HANDLER = proc do |layout, layout_opts, obj|
48
53
  layout_opts ? layout.new(obj, **layout_opts) : layout.new(obj)
49
54
  end
50
55
 
56
+ # @!visibility private
57
+ DELEGATE_ERROR_MESSAGE = "roda-phlex: :delegate is enabled, but :%s is to %s. Delegation will be disabled. Set :delegate to false to suppress this warning."
58
+ private_constant :DELEGATE_ERROR_MESSAGE
59
+
51
60
  # Configures the Phlex plugin for the Roda application.
52
61
  # @param app [Roda] The Roda application.
53
62
  # @param opts [Hash] The options for configuring the Phlex plugin.
54
63
  def self.configure(app, opts = OPTS)
55
- delegate = opts.key?(:delegate) ? opts.delete(:delegate) : true
56
- app.opts[:phlex] = opts
57
- app.opts[:phlex][:layout_handler] ||= DEFAULT_LAYOUT_HANDLER
58
-
64
+ delegate = opts.fetch(:delegate, true)
59
65
  if delegate
60
- overrides = Module.new do
61
- def app
62
- @_view_context
63
- end
66
+ delegate_on = opts.fetch(:delegate_on) { ::Phlex::SGML }
67
+ delegate_name = opts.fetch(:delegate_name, "app")
64
68
 
65
- case delegate
66
- when :all
67
- def method_missing(name, ...)
68
- if app.respond_to?(name)
69
- app.send(name, ...)
70
- else
71
- super
72
- end
73
- end
69
+ warn sprintf(DELEGATE_ERROR_MESSAGE, "delegate_on", delegate_on.inspect) unless delegate_on
70
+ warn sprintf(DELEGATE_ERROR_MESSAGE, "delegate_name", delegate_name.inspect) unless delegate_name
71
+ end
72
+
73
+ app.opts[:phlex] = opts.dup
74
+ app.opts[:phlex][:layout_handler] ||= DEFAULT_LAYOUT_HANDLER
75
+ app.opts[:phlex][:context] ||= {}
74
76
 
75
- def respond_to_missing?(name, include_private = false)
76
- app.respond_to?(name) || super
77
+ if delegate && delegate_on && delegate_name
78
+ delegate_mod = Module.new do
79
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
80
+ def #{delegate_name}
81
+ @_view_context
77
82
  end
83
+ RUBY
78
84
 
79
- when Symbol, String, Array
80
- Array(delegate).each do |delegate|
85
+ case delegate
86
+ when Array
87
+ delegate.each do |delegate|
81
88
  class_eval <<~RUBY, __FILE__, __LINE__ + 1
82
89
  def #{delegate}(...)
83
- app.#{delegate}(...)
90
+ #{delegate_name}.#{delegate}(...)
84
91
  end
85
92
  RUBY
86
93
  end
87
94
  end
88
95
  end
89
96
 
90
- ::Phlex::SGML.include(overrides)
97
+ delegate_on.include(delegate_mod)
91
98
  end
92
99
  end
93
100
 
94
101
  module InstanceMethods
95
- # Retrieves or sets the layout.
96
- # @param layout [Phlex::SGML, Undefined, nil] The layout to be set.
97
- # @return [Phlex::SGML, nil] The current layout or nil if not set.
98
- def phlex_layout(layout = Undefined)
99
- case layout
100
- when Undefined
101
- opts.dig(:phlex, :layout)
102
- when nil
103
- opts[:phlex].delete(:layout)
104
- opts[:phlex].delete(:layout_opts)
105
- when ::Phlex::SGML
106
- opts[:phlex][:layout] = layout
102
+ # Retrieves the layout class.
103
+ # @return [Class, nil] The current layout (a +Phlex::SGML+ class) or nil if not set.
104
+ def phlex_layout
105
+ return @_phlex_layout if defined?(@_phlex_layout)
106
+ @_phlex_layout = opts.dig(:phlex, :layout)
107
+ end
108
+
109
+ # Sets the layout class.
110
+ #
111
+ # @param layout [Class, nil] The layout class to be set.
112
+ # @return [Class, nil] The layout class that was set.
113
+ def set_phlex_layout(layout)
114
+ if !layout || layout <= ::Phlex::SGML
115
+ @_phlex_layout = layout
107
116
  else
108
117
  raise TypeError.new(layout)
109
118
  end
110
119
  end
111
120
 
112
- # Retrieves or sets the layout options.
113
- # @param layout_opts [Undefined, nil] The layout options to be set.
121
+ # Retrieves the layout options hash.
114
122
  # @return [Object, nil] The current layout options or nil if not set.
115
- def phlex_layout_opts(layout_opts = Undefined)
116
- case layout_opts
117
- when Undefined
118
- opts.dig(:phlex, :layout_opts)
119
- when nil
120
- opts[:phlex].delete(:layout_opts)
121
- else
122
- opts[:phlex][:layout_opts] = layout_opts
123
- end
123
+ # @note Layout options set via the plugin configuration will get `dep`ed
124
+ # for the current request. Be aware that this is a shallow copy and
125
+ # changes to nested objects will affect the original object, that is
126
+ # all subsequent requests. This is *unsafe* and should be avoided:
127
+ # ```ruby
128
+ # plugin :phlex, layout_opts: {key: {nested: "value"}}
129
+ # # ...
130
+ # # UNSAFE: Changes to phlex_layout_opts[:key] will affect the plugin config.
131
+ # phlex_layout_opts[:key][:nested] = "other value"
132
+ # ```
133
+ def phlex_layout_opts
134
+ return @_phlex_layout_opts if defined?(@_phlex_layout_opts)
135
+ @_phlex_layout_opts = opts.dig(:phlex, :layout_opts).dup
136
+ end
137
+
138
+ # Sets the layout options.
139
+ # @param layout_opts [Object, nil] The layout options to be set.
140
+ # @return [Object, nil] The layout options that were set.
141
+ # @note The {DEFAULT_LAYOUT_HANDLER} expects +layout_opts+ to be a +Hash+.
142
+ def set_phlex_layout_opts(layout_opts)
143
+ @_phlex_layout_opts = layout_opts
124
144
  end
125
145
 
126
- # Retrieves or sets the layout handler.
127
- # @param handler [#call, Undefined, nil] The layout handler to be set.
128
- # @return [#call, nil] The current layout handler or nil if not set.
129
- def phlex_layout_handler(handler = Undefined)
130
- case handler
131
- when Undefined
132
- opts.dig(:phlex, :layout_handler)
133
- when nil
134
- opts[:phlex].delete(:layout_handler)
146
+ # Retrieves the layout handler.
147
+ # @return [#call] The current layout handler.
148
+ def phlex_layout_handler
149
+ return @_phlex_layout_handler if defined?(@_phlex_layout_handler)
150
+ @_phlex_layout_handler = opts.dig(:phlex, :layout_handler)
151
+ end
152
+
153
+ # Sets the layout handler.
154
+ # Use +nil+ or +:default: to reset the layout handler to the {DEFAULT_LAYOUT_HANDLER}.
155
+ def set_phlex_layout_handler(handler)
156
+ @_phlex_layout_handler = case handler
157
+ when nil, :default
158
+ DEFAULT_LAYOUT_HANDLER
135
159
  else
136
- opts[:phlex][:layout_handler] = handler
160
+ handler
137
161
  end
138
162
  end
139
163
 
164
+ # Retrieves the Phlex context.
165
+ # @return [Hash, nil] The current Phlex context.
166
+ def phlex_context
167
+ return @_phlex_context if defined?(@_phlex_context)
168
+ @phlex_context = opts.dig(:phlex, :context).dup
169
+ end
170
+
171
+ # Sets the Phlex context.
172
+ # @param context [Hash] The Phlex context to be set.
173
+ # @return [Hash] The Phlex context that was set.
174
+ def set_phlex_context(context)
175
+ @_phlex_context = context
176
+ end
177
+
140
178
  # Renders a Phlex object.
141
179
  # @param obj [Phlex::SGML] The Phlex object to be rendered.
180
+ # @param layout [Class, nil] The layout to be used for rendering. Defaults to the layout set by {#phlex_layout}.
181
+ # - The layout class will be initialized with the object and layout options from #{phlex_layout_opts} via {#phlex_layout_handler}.
182
+ # - +nil+ or +false+ will disable layout and render the +obj+ directly.
183
+ # @param context [Hash, nil] The Phlex context to be used for rendering. Defaults to the context set by {#phlex_context}.
142
184
  # @param content_type [String, nil] The content type of the response.
143
185
  # @param stream [Boolean] Whether to stream the response or not.
144
- def phlex(obj, content_type: nil, stream: false)
186
+ def phlex(obj, layout: phlex_layout, context: phlex_context, content_type: nil, stream: false)
145
187
  raise TypeError.new(obj) unless obj.is_a?(::Phlex::SGML)
146
188
 
147
189
  content_type ||= "image/svg+xml" if obj.is_a?(::Phlex::SVG)
148
190
  response["Content-Type"] = content_type if content_type
149
191
 
150
- phlex_opts = opts[:phlex]
151
- renderer = if (layout = phlex_opts[:layout])
152
- phlex_layout_handler.call(layout, phlex_opts[:layout_opts], obj)
192
+ renderer = if layout
193
+ phlex_layout_handler.call(layout, phlex_layout_opts, obj)
153
194
  else
154
195
  obj
155
196
  end
156
197
 
198
+ opts = {view_context: self}
199
+ if context
200
+ opts[:context] = if context.is_a?(::Phlex::Context)
201
+ context
202
+ else
203
+ ::Phlex::Context.new(context)
204
+ end
205
+ end
206
+
157
207
  if stream
158
208
  self.stream do |out|
159
- renderer.call(out, view_context: self)
209
+ renderer.call(out, **opts)
160
210
  end
161
211
  else
162
- renderer.call(view_context: self)
212
+ renderer.call(**opts)
163
213
  end
164
214
  end
165
215
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roda-phlex
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Schulze
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-08-28 00:00:00.000000000 Z
10
+ date: 2025-01-27 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: phlex
@@ -17,6 +16,9 @@ dependencies:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
18
  version: 1.7.0
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '2'
20
22
  type: :runtime
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -24,6 +26,9 @@ dependencies:
24
26
  - - ">="
25
27
  - !ruby/object:Gem::Version
26
28
  version: 1.7.0
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '2'
27
32
  - !ruby/object:Gem::Dependency
28
33
  name: roda
29
34
  requirement: !ruby/object:Gem::Requirement
@@ -47,8 +52,10 @@ extra_rdoc_files: []
47
52
  files:
48
53
  - ".devcontainer/Gemfile"
49
54
  - ".devcontainer/devcontainer.json"
55
+ - ".markdownlint.yml"
50
56
  - ".rspec"
51
57
  - ".standard.yml"
58
+ - ".yardopts"
52
59
  - CHANGELOG.md
53
60
  - CODE_OF_CONDUCT.md
54
61
  - LICENSE.txt
@@ -63,7 +70,6 @@ metadata:
63
70
  homepage_uri: https://github.com/fnordfish/roda-phlex
64
71
  source_code_uri: https://github.com/fnordfish/roda-phlex
65
72
  changelog_uri: https://github.com/fnordfish/roda-phlex/blob/main/CHANGELOG.md
66
- post_install_message:
67
73
  rdoc_options: []
68
74
  require_paths:
69
75
  - lib
@@ -78,8 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
84
  - !ruby/object:Gem::Version
79
85
  version: '0'
80
86
  requirements: []
81
- rubygems_version: 3.5.17
82
- signing_key:
87
+ rubygems_version: 3.6.2
83
88
  specification_version: 4
84
89
  summary: A Phlex adapter for Roda
85
90
  test_files: []