@@ -26,9 +26,6 @@ module RodaPlugins
2626 # (like "ApplicationView") to avoid polluting the global namespace.
2727 # - `:delegate_name`: The name of the method that delegates to the Roda app. Defaults to `"app"`.
2828 module Phlex
29- Undefined = Object . new
30- private_constant :Undefined
31-
3229 Error = Class . new ( StandardError )
3330
3431 # Custom TypeError class for Phlex errors.
@@ -101,90 +98,98 @@ def #{delegate}(...)
10198 end
10299
103100 module InstanceMethods
104- # Retrieves or sets the layout.
105- # When no argument is provided, it returns the current layout.
106- # Use +nil+ or +false+ to disable layout.
107- #
108- # @param layout [Class, nil, false] The layout (a +Phlex::SGML+ class) to be set.
101+ # Retrieves the layout class.
109102 # @return [Class, nil] The current layout (a +Phlex::SGML+ class) or nil if not set.
110- def phlex_layout ( layout = Undefined )
111- case layout
112- when Undefined
113- opts . dig ( :phlex , :layout )
114- when nil , false
115- opts [ :phlex ] . delete ( :layout )
116- else
117- if layout <= ::Phlex ::SGML
118- opts [ :phlex ] [ :layout ] = layout
119- else
120- raise TypeError . new ( layout )
121- end
122- end
103+ def phlex_layout
104+ return @_phlex_layout if defined? ( @_phlex_layout )
105+ @_phlex_layout = opts . dig ( :phlex , :layout )
123106 end
124107
125- # Retrieves or sets the layout options.
126- # When no argument is provided, it returns the current layout options.
127- # Use +nil+ to delete layout options.
108+ # Sets the layout class.
128109 #
129- # @note The {DEFAULT_LAYOUT_HANDLER} expects +layout_opts+ to be a +Hash+.
130- # @param layout_opts [Object, nil] The layout options to be set, usually a +Hash+.
131- # @return [Object, nil] The current layout options or nil if not set.
132- def phlex_layout_opts ( layout_opts = Undefined )
133- case layout_opts
134- when Undefined
135- opts . dig ( :phlex , :layout_opts )
136- when nil
137- opts [ :phlex ] . delete ( :layout_opts )
110+ # @param layout [Class, nil] The layout class to be set.
111+ # @return [Class, nil] The layout class that was set.
112+ def set_phlex_layout ( layout )
113+ if !layout || layout <= ::Phlex ::SGML
114+ @_phlex_layout = layout
138115 else
139- opts [ :phlex ] [ :layout_opts ] = layout_opts
116+ raise TypeError . new ( layout )
140117 end
141118 end
142119
143- # Retrieves or sets the layout handler.
144- # When no argument is provided, it returns the current layout handler.
145- # Use +nil+ or +:default: to reset the layout handler to the {DEFAULT_LAYOUT_HANDLER}.
146- #
147- # @param handler [#call, nil, :default] The layout handler to be set.
120+ # Retrieves the layout options hash.
121+ # @return [Object, nil] The current layout options or nil if not set.
122+ # @note Layout options set via the plugin configuration will get `dep`ed
123+ # for the current request. Be aware that this is a shallow copy and
124+ # changes to nested objects will affect the original object, that is
125+ # all subsequent requests. This is *unsafe* and should be avoided:
126+ # ```ruby
127+ # plugin :phlex, layout_opts: {key: {nested: "value"}}
128+ # # ...
129+ # # UNSAFE: Changes to phlex_layout_opts[:key] will affect the plugin config.
130+ # phlex_layout_opts[:key][:nested] = "other value"
131+ # ```
132+ def phlex_layout_opts
133+ return @_phlex_layout_opts if defined? ( @_phlex_layout_opts )
134+ @_phlex_layout_opts = opts . dig ( :phlex , :layout_opts ) . dup
135+ end
136+
137+ # Sets the layout options.
138+ # @param layout_opts [Object, nil] The layout options to be set.
139+ # @return [Object, nil] The layout options that were set.
140+ # @note The {DEFAULT_LAYOUT_HANDLER} expects +layout_opts+ to be a +Hash+.
141+ def set_phlex_layout_opts ( layout_opts )
142+ @_phlex_layout_opts = layout_opts
143+ end
144+
145+ # Retrieves the layout handler.
148146 # @return [#call] The current layout handler.
149- def phlex_layout_handler ( handler = Undefined )
150- case handler
151- when Undefined
152- opts . dig ( :phlex , :layout_handler )
147+ def phlex_layout_handler
148+ return @_phlex_layout_handler if defined? ( @_phlex_layout_handler )
149+ @_phlex_layout_handler = opts . dig ( :phlex , :layout_handler )
150+ end
151+
152+ # Sets the layout handler.
153+ # Use +nil+ or +:default: to reset the layout handler to the {DEFAULT_LAYOUT_HANDLER}.
154+ def set_phlex_layout_handler ( handler )
155+ @_phlex_layout_handler = case handler
153156 when nil , :default
154- opts [ :phlex ] [ :layout_handler ] = DEFAULT_LAYOUT_HANDLER
157+ DEFAULT_LAYOUT_HANDLER
155158 else
156- opts [ :phlex ] [ :layout_handler ] = handler
159+ handler
157160 end
158161 end
159162
160- # Retrieves or sets the Phlex context.
161- # When no argument is provided, it returns the current Phlex context.
162- #
163+ # Retrieves the Phlex context.
164+ # @return [Hash, nil] The current Phlex context.
165+ def phlex_context
166+ return @_phlex_context if defined? ( @_phlex_context )
167+ @phlex_context = opts . dig ( :phlex , :context ) . dup
168+ end
169+
170+ # Sets the Phlex context.
163171 # @param context [Hash] The Phlex context to be set.
164- # @return [Hash] The current Phlex context.
165- def phlex_context ( context = Undefined )
166- case context
167- when Undefined
168- opts . dig ( :phlex , :context )
169- else
170- opts [ :phlex ] [ :context ] = context
171- end
172+ # @return [Hash] The Phlex context that was set.
173+ def set_phlex_context ( context )
174+ @_phlex_context = context
172175 end
173176
174177 # Renders a Phlex object.
175178 # @param obj [Phlex::SGML] The Phlex object to be rendered.
176- # @param context [Hash] The Phlex context to be used for rendering.
179+ # @param layout [Class, nil] The layout to be used for rendering. Defaults to the layout set by {#phlex_layout}.
180+ # - The layout class will be initialized with the object and layout options from #{phlex_layout_opts} via {#phlex_layout_handler}.
181+ # - +nil+ or +false+ will disable layout and render the +obj+ directly.
182+ # @param context [Hash, nil] The Phlex context to be used for rendering. Defaults to the context set by {#phlex_context}.
177183 # @param content_type [String, nil] The content type of the response.
178184 # @param stream [Boolean] Whether to stream the response or not.
179- def phlex ( obj , context : phlex_context , content_type : nil , stream : false )
185+ def phlex ( obj , layout : phlex_layout , context : phlex_context , content_type : nil , stream : false )
180186 raise TypeError . new ( obj ) unless obj . is_a? ( ::Phlex ::SGML )
181187
182188 content_type ||= "image/svg+xml" if obj . is_a? ( ::Phlex ::SVG )
183189 response [ "Content-Type" ] = content_type if content_type
184190
185- phlex_opts = opts [ :phlex ]
186- renderer = if ( layout = phlex_opts [ :layout ] )
187- phlex_layout_handler . call ( layout , phlex_opts [ :layout_opts ] , obj )
191+ renderer = if layout
192+ phlex_layout_handler . call ( layout , phlex_layout_opts , obj )
188193 else
189194 obj
190195 end
0 commit comments