gloo 3.0.1 → 3.1.0

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.
@@ -0,0 +1,389 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # A web page hosted in a gloo web server.
5
+ #
6
+
7
+ module Gloo
8
+ module Objs
9
+ class Page < Gloo::Core::Obj
10
+
11
+ KEYWORD = 'page'.freeze
12
+ KEYWORD_SHORT = 'page'.freeze
13
+
14
+ # Events
15
+ ON_RENDER = 'on_render'.freeze
16
+ ON_RENDERED = 'on_rendered'.freeze
17
+
18
+ # Parameters used during render.
19
+ PARAMS = 'params'.freeze
20
+
21
+ # Content
22
+ HEAD = 'head'.freeze
23
+ BODY = 'body'.freeze
24
+ CONTENT = 'content'.freeze
25
+ TITLE = 'title'.freeze
26
+
27
+ # Layout for this page.
28
+ # If not specified, use the layout for the app.
29
+ LAYOUT = 'layout'.freeze
30
+
31
+ # Return Content type and HTML Code
32
+ CONTENT_TYPE = 'content_type'.freeze
33
+ HTML_CONTENT = 'html'.freeze
34
+ TEXT_CONTENT = 'text'.freeze
35
+ JSON_CONTENT = 'json'.freeze
36
+ RETURN_CODE = 'return_code'.freeze
37
+
38
+ #
39
+ # The name of the object type.
40
+ #
41
+ def self.typename
42
+ return KEYWORD
43
+ end
44
+
45
+ #
46
+ # The short name of the object type.
47
+ #
48
+ def self.short_typename
49
+ return KEYWORD_SHORT
50
+ end
51
+
52
+ #
53
+ # Set the value with any necessary type conversions.
54
+ #
55
+ def set_value( new_value )
56
+ self.value = new_value.to_s
57
+ end
58
+
59
+ #
60
+ # Does this object support multi-line values?
61
+ # Initially only true for scripts.
62
+ #
63
+ def multiline_value?
64
+ return false
65
+ end
66
+
67
+ #
68
+ # Get the head element.
69
+ #
70
+ def head
71
+ return find_child HEAD
72
+ end
73
+
74
+ #
75
+ # Get the header content.
76
+ # This might be in a content child, or it might be
77
+ # the head object itself.
78
+ #
79
+ def head_content
80
+ head_obj = head
81
+ return nil unless head_obj
82
+
83
+ content_obj = head_obj.find_child CONTENT
84
+ return content_obj ? content_obj : head_obj
85
+ end
86
+
87
+ #
88
+ # Get the body element.
89
+ #
90
+ def body
91
+ return find_child BODY
92
+ end
93
+
94
+ #
95
+ # Get the body content.
96
+ # This might be in a content child, or it might be
97
+ # the body object itself.
98
+ #
99
+ def body_content
100
+ body_obj = body
101
+ return nil unless body_obj
102
+
103
+ content_obj = body_obj.find_child CONTENT
104
+ return content_obj ? content_obj : body_obj
105
+ end
106
+
107
+ #
108
+ # Get the params hash from the child object.
109
+ # Returns nil if there is none.
110
+ #
111
+ def params_hash
112
+ params_can = find_child PARAMS
113
+ return nil unless params_can
114
+
115
+ h = {}
116
+ params_can.children.each do |o|
117
+ h[ o.name ] = o.value
118
+ end
119
+
120
+ return h
121
+ end
122
+
123
+ #
124
+ # Get the return code.
125
+ # SUCCESS is the default if none is set.
126
+ #
127
+ def return_code
128
+ code = find_child RETURN_CODE
129
+ return code ? code.value : Gloo::WebSvr::ResponseCode::SUCCESS
130
+ end
131
+
132
+ #
133
+ # Get the content type.
134
+ #
135
+ def content_type
136
+ type = find_child CONTENT_TYPE
137
+ return type ? type.value : nil
138
+ end
139
+
140
+ #
141
+ # Get the layout for this page.
142
+ #
143
+ def page_layout
144
+ o = find_child LAYOUT
145
+ return nil unless o
146
+
147
+ o = Gloo::Objs::Alias.resolve_alias( @engine, o )
148
+ return o
149
+ end
150
+
151
+ #
152
+ # Is the return type HTML?
153
+ #
154
+ def is_html?
155
+ return true if content_type.nil?
156
+ return content_type == HTML_CONTENT
157
+ end
158
+
159
+ #
160
+ # Is the return type TEXT?
161
+ #
162
+ def is_text?
163
+ return content_type == TEXT_CONTENT
164
+ end
165
+
166
+ #
167
+ # Is the return type JSON?
168
+ #
169
+ def is_json?
170
+ return content_type == JSON_CONTENT
171
+ end
172
+
173
+
174
+ # ---------------------------------------------------------------------
175
+ # Events
176
+ # ---------------------------------------------------------------------
177
+
178
+ #
179
+ # Run the on render script if there is one.
180
+ #
181
+ def run_on_render
182
+ o = find_child ON_RENDER
183
+ return unless o
184
+
185
+ Gloo::Exec::Dispatch.message( @engine, 'run', o )
186
+ end
187
+
188
+ #
189
+ # Run the on rendered script if there is one.
190
+ #
191
+ def run_on_rendered
192
+ o = find_child ON_RENDERED
193
+ return unless o
194
+
195
+ Gloo::Exec::Dispatch.message( @engine, 'run', o )
196
+ end
197
+
198
+
199
+ # ---------------------------------------------------------------------
200
+ # Children
201
+ # ---------------------------------------------------------------------
202
+
203
+ #
204
+ # Does this object have children to add when an object
205
+ # is created in interactive mode?
206
+ # This does not apply during obj load, etc.
207
+ #
208
+ def add_children_on_create?
209
+ return true
210
+ end
211
+
212
+ #
213
+ # Add children to this object.
214
+ # This is used by containers to add children needed
215
+ # for default configurations.
216
+ #
217
+ def add_default_children
218
+ fac = @engine.factory
219
+
220
+ fac.create_script ON_RENDER, '', self
221
+ fac.create_script ON_RENDERED, '', self
222
+ fac.create_can PARAMS, self
223
+
224
+ params = { :name => HEAD,
225
+ :type => Gloo::Objs::Element.typename,
226
+ :value => nil,
227
+ :parent => self }
228
+ head = fac.create params
229
+ content = fac.create_can CONTENT, head
230
+ params = { :name => TITLE,
231
+ :type => Gloo::Objs::Element.typename,
232
+ :value => nil,
233
+ :parent => content }
234
+ title = fac.create params
235
+
236
+ params = { :name => BODY,
237
+ :type => Gloo::Objs::Element.typename,
238
+ :value => nil,
239
+ :parent => self }
240
+ body = fac.create params
241
+ content = fac.create_can CONTENT, body
242
+ end
243
+
244
+
245
+ # ---------------------------------------------------------------------
246
+ # Messages
247
+ # ---------------------------------------------------------------------
248
+
249
+ #
250
+ # Get a list of message names that this object receives.
251
+ #
252
+ def self.messages
253
+ return super + [ 'render' ]
254
+ end
255
+
256
+ #
257
+ # Get the expiration date for the certificate.
258
+ #
259
+ def msg_render
260
+ content = self.render
261
+ @engine.heap.it.set_to content
262
+ return content
263
+ end
264
+
265
+ # ---------------------------------------------------------------------
266
+ # Render
267
+ # ---------------------------------------------------------------------
268
+
269
+ #
270
+ # Wrap the content in the tag with id and class.
271
+ #
272
+ def wrap( tag, content, id=nil, classes=nil )
273
+ return "<#{tag}>#{content}</#{tag}>"
274
+ end
275
+
276
+ #
277
+ # Is there a redirect page set in the running app?
278
+ #
279
+ def redirect_set?
280
+ return false unless @engine.app_running?
281
+ return @engine.running_app.obj.redirect
282
+ end
283
+
284
+ #
285
+ # Render the page.
286
+ #
287
+ def render
288
+ run_on_render
289
+ return nil if redirect_set?
290
+
291
+ params = params_hash
292
+
293
+ if is_html?
294
+ contents = render_html params
295
+ elsif is_json?
296
+ contents = render_json
297
+ elsif is_text?
298
+ contents = render_text params
299
+ else
300
+ @engine.log.error "Unknown content type: #{content_type}"
301
+ return nil
302
+ end
303
+
304
+ run_on_rendered
305
+ return nil if redirect_set?
306
+
307
+ return contents
308
+ end
309
+
310
+ #
311
+ # Render the page as HTML.
312
+ #
313
+ def render_html params
314
+ head_obj = render_with_params head_content, :render_html, params
315
+ body_obj = render_with_params body_content, :render_html, params
316
+
317
+ layout = page_layout_or_app_layout
318
+ if layout
319
+ @engine.log.debug "Using Page Layout: #{layout.pn}"
320
+ contents = layout.render_layout( head_obj, body_obj )
321
+ else
322
+ @engine.log.debug "No layout for page."
323
+ contents = wrap( 'html', head_obj + body_obj )
324
+ end
325
+
326
+ return Gloo::WebSvr::Response.html_response(
327
+ @engine, contents, return_code )
328
+ end
329
+
330
+ #
331
+ # Get the layout for this page or if none for the app.
332
+ #
333
+ def page_layout_or_app_layout
334
+ layout = page_layout
335
+ return layout if layout
336
+
337
+ return nil unless @engine.app_running?
338
+ return @engine.running_app.obj.default_page_layout
339
+ end
340
+
341
+ #
342
+ # Render the page as JSON.
343
+ #
344
+ def render_json
345
+ json_content = Gloo::Objs::Json.convert_obj_to_json( body )
346
+
347
+ return Gloo::WebSvr::Response.json_response( @engine, json_content, return_code )
348
+ end
349
+
350
+ #
351
+ # Render the page as TEXT.
352
+ #
353
+ def render_text params
354
+ text_content = render_with_params body_content, :render_text, params
355
+ return Gloo::WebSvr::Response.text_response( @engine, text_content, return_code )
356
+ end
357
+
358
+ #
359
+ # Given an object and a render message, render the object.
360
+ # If the obj is nil, return an empty string.
361
+ # If the params are nil, no param rendering is done.
362
+ #
363
+ def render_with_params obj, render_ƒ, params
364
+ return '' unless obj
365
+
366
+ content = Element.render_obj( obj, render_ƒ, @engine )
367
+ # content = Page.render_params( content, params ) if params
368
+ content = @engine.running_app.obj.embedded_renderer.render content, params
369
+
370
+ return content
371
+ end
372
+
373
+ #
374
+ # Render content with the given params.
375
+ # Params might be nil, in which case the content
376
+ # is returned with no changes.
377
+ #
378
+ def self.render_params content, params
379
+ return content unless params
380
+
381
+ renderer = ERB.new( content )
382
+ content = renderer.result_with_hash( params )
383
+
384
+ return content
385
+ end
386
+
387
+ end
388
+ end
389
+ end
@@ -0,0 +1,204 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # A partial page.
5
+ #
6
+
7
+ module Gloo
8
+ module Objs
9
+ class Partial < Gloo::Core::Obj
10
+
11
+ KEYWORD = 'partial'.freeze
12
+ KEYWORD_SHORT = 'part'.freeze
13
+
14
+ # Events
15
+ ON_RENDER = 'on_render'.freeze
16
+ ON_RENDERED = 'on_rendered'.freeze
17
+
18
+ # Parameters used during render.
19
+ PARAMS = 'params'.freeze
20
+
21
+ # Content
22
+ CONTENT = 'content'.freeze
23
+
24
+
25
+ #
26
+ # The name of the object type.
27
+ #
28
+ def self.typename
29
+ return KEYWORD
30
+ end
31
+
32
+ #
33
+ # The short name of the object type.
34
+ #
35
+ def self.short_typename
36
+ return KEYWORD_SHORT
37
+ end
38
+
39
+ #
40
+ # Set the value with any necessary type conversions.
41
+ #
42
+ def set_value( new_value )
43
+ self.value = new_value.to_s
44
+ end
45
+
46
+ #
47
+ # Does this object support multi-line values?
48
+ # Initially only true for scripts.
49
+ #
50
+ def multiline_value?
51
+ return false
52
+ end
53
+
54
+ #
55
+ # Get the content obj.
56
+ #
57
+ def content
58
+ return find_child CONTENT
59
+ end
60
+
61
+ #
62
+ # Get the params hash from the child object.
63
+ # Returns nil if there is none.
64
+ #
65
+ def params_hash
66
+ params_can = find_child PARAMS
67
+ return nil unless params_can
68
+
69
+ h = {}
70
+ params_can.children.each do |o|
71
+ h[ o.name ] = o.value
72
+ end
73
+
74
+ return h
75
+ end
76
+
77
+
78
+ # ---------------------------------------------------------------------
79
+ # Events
80
+ # ---------------------------------------------------------------------
81
+
82
+ #
83
+ # Run the on render script if there is one.
84
+ #
85
+ def run_on_render
86
+ o = find_child ON_RENDER
87
+ return unless o
88
+
89
+ Gloo::Exec::Dispatch.message( @engine, 'run', o )
90
+ end
91
+
92
+ #
93
+ # Run the on rendered script if there is one.
94
+ #
95
+ def run_on_rendered
96
+ o = find_child ON_RENDERED
97
+ return unless o
98
+
99
+ Gloo::Exec::Dispatch.message( @engine, 'run', o )
100
+ end
101
+
102
+
103
+ # ---------------------------------------------------------------------
104
+ # Children
105
+ # ---------------------------------------------------------------------
106
+
107
+ #
108
+ # Does this object have children to add when an object
109
+ # is created in interactive mode?
110
+ # This does not apply during obj load, etc.
111
+ #
112
+ def add_children_on_create?
113
+ return true
114
+ end
115
+
116
+ #
117
+ # Add children to this object.
118
+ # This is used by containers to add children needed
119
+ # for default configurations.
120
+ #
121
+ def add_default_children
122
+ fac = @engine.factory
123
+
124
+ fac.create_script ON_RENDER, '', self
125
+ fac.create_script ON_RENDERED, '', self
126
+
127
+ fac.create_can PARAMS, self
128
+ fac.create_can CONTENT, self
129
+ end
130
+
131
+
132
+ # ---------------------------------------------------------------------
133
+ # Messages
134
+ # ---------------------------------------------------------------------
135
+
136
+ #
137
+ # Get a list of message names that this object receives.
138
+ #
139
+ def self.messages
140
+ return super + [ 'render' ]
141
+ end
142
+
143
+ #
144
+ # Get the expiration date for the certificate.
145
+ #
146
+ def msg_render
147
+ part_content = self.render
148
+ @engine.heap.it.set_to part_content
149
+ return part_content
150
+ end
151
+
152
+ # ---------------------------------------------------------------------
153
+ # Render
154
+ # ---------------------------------------------------------------------
155
+
156
+ #
157
+ # Render the page.
158
+ # Use the specified render function or HTML by default.
159
+ #
160
+ def render( render_ƒ = :render_html )
161
+ run_on_render
162
+
163
+ part_content = ''
164
+ content.children.each do |e|
165
+ part_content << e.send( render_ƒ )
166
+ end
167
+
168
+ # part_content = Page.render_params part_content, params_hash
169
+ part_content = @engine.running_app.obj.embedded_renderer.render part_content, params_hash
170
+
171
+ run_on_rendered
172
+ return part_content
173
+ end
174
+
175
+ #
176
+ # Render the layout with the body and head params.
177
+ #
178
+ def render_layout( head, body )
179
+ run_on_render
180
+
181
+ part_content = ''
182
+ content.children.each do |e|
183
+ e = Gloo::Objs::Alias.resolve_alias( @engine, e )
184
+
185
+ obj = e.find_child CONTENT
186
+ e = obj if obj
187
+
188
+ part_content << Element.render_obj( e, :render_html, @engine )
189
+ end
190
+
191
+ params = params_hash || {}
192
+ params[ 'head' ] = head
193
+ params[ 'body' ] = body
194
+
195
+ # part_content = Page.render_params part_content, params
196
+ part_content = @engine.running_app.obj.embedded_renderer.render part_content, params
197
+
198
+ run_on_rendered
199
+ return part_content
200
+ end
201
+
202
+ end
203
+ end
204
+ end