gloo 3.0.1 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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