gloo 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/gloo.gemspec +1 -0
- data/lib/VERSION +1 -1
- data/lib/VERSION_NOTES +10 -0
- data/lib/gloo/app/engine.rb +37 -4
- data/lib/gloo/app/log.rb +1 -2
- data/lib/gloo/app/running_app.rb +41 -0
- data/lib/gloo/core/factory.rb +3 -0
- data/lib/gloo/core/gloo_system.rb +5 -0
- data/lib/gloo/objs/basic/function.rb +169 -0
- data/lib/gloo/objs/basic/untyped.rb +1 -1
- data/lib/gloo/objs/web/json.rb +14 -1
- data/lib/gloo/objs/web/uri.rb +13 -1
- data/lib/gloo/objs/web_svr/element.rb +244 -0
- data/lib/gloo/objs/web_svr/page.rb +389 -0
- data/lib/gloo/objs/web_svr/partial.rb +204 -0
- data/lib/gloo/objs/web_svr/svr.rb +299 -0
- data/lib/gloo/verbs/cls.rb +1 -1
- data/lib/gloo/verbs/redirect.rb +56 -0
- data/lib/gloo/web_svr/asset.rb +194 -0
- data/lib/gloo/web_svr/config.rb +56 -0
- data/lib/gloo/web_svr/embedded_renderer.rb +91 -0
- data/lib/gloo/web_svr/handler.rb +120 -0
- data/lib/gloo/web_svr/request.rb +107 -0
- data/lib/gloo/web_svr/response.rb +118 -0
- data/lib/gloo/web_svr/response_code.rb +69 -0
- data/lib/gloo/web_svr/router.rb +179 -0
- data/lib/gloo/web_svr/server.rb +97 -0
- metadata +32 -2
@@ -0,0 +1,299 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# A web web server running inside gloo.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Gloo
|
8
|
+
module Objs
|
9
|
+
class Svr < Gloo::Core::Obj
|
10
|
+
|
11
|
+
KEYWORD = 'server'.freeze
|
12
|
+
KEYWORD_SHORT = 'svr'.freeze
|
13
|
+
|
14
|
+
# Configuration
|
15
|
+
SCHEME = 'scheme'.freeze
|
16
|
+
HOST = 'host'.freeze
|
17
|
+
PORT = 'port'.freeze
|
18
|
+
|
19
|
+
# Events
|
20
|
+
ON_START = 'on_start'.freeze
|
21
|
+
ON_STOP = 'on_stop'.freeze
|
22
|
+
|
23
|
+
# Container with pages in the web app.
|
24
|
+
PAGES = 'pages'.freeze
|
25
|
+
|
26
|
+
# Default layout for pages.
|
27
|
+
LAYOUT = 'layout'.freeze
|
28
|
+
|
29
|
+
# Alias to the home and error pages
|
30
|
+
HOME = 'home'.freeze
|
31
|
+
ERR_PAGE = 'error'.freeze
|
32
|
+
|
33
|
+
|
34
|
+
# Messages
|
35
|
+
SERVER_NOT_RUNNING = 'The web server is not running and cannot be stopped'.freeze
|
36
|
+
|
37
|
+
#
|
38
|
+
# Should the current request be redirected?
|
39
|
+
# If the redirect is set, then use that page instead
|
40
|
+
# of the one requested.
|
41
|
+
#
|
42
|
+
attr_accessor :redirect, :router, :asset, :embedded_renderer
|
43
|
+
|
44
|
+
#
|
45
|
+
# The name of the object type.
|
46
|
+
#
|
47
|
+
def self.typename
|
48
|
+
return KEYWORD
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# The short name of the object type.
|
53
|
+
#
|
54
|
+
def self.short_typename
|
55
|
+
return KEYWORD_SHORT
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Set the value with any necessary type conversions.
|
60
|
+
#
|
61
|
+
def set_value( new_value )
|
62
|
+
self.value = new_value.to_s
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Does this object support multi-line values?
|
67
|
+
# Initially only true for scripts.
|
68
|
+
#
|
69
|
+
def multiline_value?
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# Get the Scheme (http or https) from the child object.
|
75
|
+
# Returns nil if there is none.
|
76
|
+
#
|
77
|
+
def scheme_value
|
78
|
+
scheme = find_child SCHEME
|
79
|
+
return nil unless scheme
|
80
|
+
|
81
|
+
return scheme.value
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Get the host from the child object.
|
86
|
+
# Returns nil if there is none.
|
87
|
+
#
|
88
|
+
def host_value
|
89
|
+
host = find_child HOST
|
90
|
+
return nil unless host
|
91
|
+
|
92
|
+
return host.value
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# Get the port from the child object.
|
97
|
+
# Returns nil if there is none.
|
98
|
+
#
|
99
|
+
def port_value
|
100
|
+
port = find_child PORT
|
101
|
+
return nil unless port
|
102
|
+
|
103
|
+
return port.value
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
#
|
108
|
+
# Get the default layout for the app.
|
109
|
+
#
|
110
|
+
def default_page_layout
|
111
|
+
o = find_child LAYOUT
|
112
|
+
return nil unless o
|
113
|
+
|
114
|
+
o = Gloo::Objs::Alias.resolve_alias( @engine, o )
|
115
|
+
return o
|
116
|
+
end
|
117
|
+
|
118
|
+
# ---------------------------------------------------------------------
|
119
|
+
# Children
|
120
|
+
# ---------------------------------------------------------------------
|
121
|
+
|
122
|
+
#
|
123
|
+
# Does this object have children to add when an object
|
124
|
+
# is created in interactive mode?
|
125
|
+
# This does not apply during obj load, etc.
|
126
|
+
#
|
127
|
+
def add_children_on_create?
|
128
|
+
return true
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# Add children to this object.
|
133
|
+
# This is used by containers to add children needed
|
134
|
+
# for default configurations.
|
135
|
+
#
|
136
|
+
def add_default_children
|
137
|
+
fac = @engine.factory
|
138
|
+
|
139
|
+
fac.create_string SCHEME, 'http', self
|
140
|
+
fac.create_string HOST, 'localhost', self
|
141
|
+
fac.create_string PORT, '8080', self
|
142
|
+
|
143
|
+
fac.create_script ON_START, '', self
|
144
|
+
fac.create_script ON_STOP, '', self
|
145
|
+
|
146
|
+
fac.create_can PAGES, self
|
147
|
+
fac.create_can HOME, self
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
# ---------------------------------------------------------------------
|
152
|
+
# Messages
|
153
|
+
# ---------------------------------------------------------------------
|
154
|
+
|
155
|
+
#
|
156
|
+
# Get a list of message names that this object receives.
|
157
|
+
#
|
158
|
+
def self.messages
|
159
|
+
return super + [ 'start', 'stop' ]
|
160
|
+
end
|
161
|
+
|
162
|
+
#
|
163
|
+
# Start the gloo web server.
|
164
|
+
#
|
165
|
+
def msg_start
|
166
|
+
@engine.log.debug "Starting web server…"
|
167
|
+
# @engine.log.quiet = true
|
168
|
+
|
169
|
+
# Set running app to this object.
|
170
|
+
@engine.start_running_app( self )
|
171
|
+
# The running app will call the start function (below)
|
172
|
+
end
|
173
|
+
|
174
|
+
#
|
175
|
+
# Stop the running web server.
|
176
|
+
#
|
177
|
+
def msg_stop
|
178
|
+
if @web_server
|
179
|
+
@engine.stop_running_app
|
180
|
+
# The running app will call the stop function (below)
|
181
|
+
else
|
182
|
+
@engine.log.error SERVER_NOT_RUNNING
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# ---------------------------------------------------------------------
|
187
|
+
# Start and Stop Events
|
188
|
+
# Might come from messages or from other application events.
|
189
|
+
# RunningApp fires these events.
|
190
|
+
# ---------------------------------------------------------------------
|
191
|
+
|
192
|
+
#
|
193
|
+
# Start running the web server.
|
194
|
+
#
|
195
|
+
def start
|
196
|
+
config = Gloo::WebSvr::Config.new( scheme_value, host_value, port_value )
|
197
|
+
@engine.log.info "Web Server URL: #{config.base_url}"
|
198
|
+
|
199
|
+
handler = Gloo::WebSvr::Handler.new( @engine, self )
|
200
|
+
@web_server = Gloo::WebSvr::Server.new( @engine, handler, config )
|
201
|
+
@web_server.start
|
202
|
+
|
203
|
+
@router = Gloo::WebSvr::Router.new( @engine, self )
|
204
|
+
@router.add_page_routes
|
205
|
+
|
206
|
+
@asset = Gloo::WebSvr::Asset.new( @engine, self )
|
207
|
+
@asset.add_asset_routes
|
208
|
+
|
209
|
+
@embedded_renderer = Gloo::WebSvr::EmbeddedRenderer.new( @engine, self )
|
210
|
+
|
211
|
+
run_on_start
|
212
|
+
@engine.log.info "Web server started and listening…"
|
213
|
+
end
|
214
|
+
|
215
|
+
#
|
216
|
+
# Stop the running web server.
|
217
|
+
#
|
218
|
+
def stop
|
219
|
+
@engine.log.info "Stopping web server…"
|
220
|
+
@web_server.stop
|
221
|
+
@web_server = nil
|
222
|
+
|
223
|
+
run_on_stop
|
224
|
+
@engine.log.info "Web server stopped…"
|
225
|
+
end
|
226
|
+
|
227
|
+
|
228
|
+
# ---------------------------------------------------------------------
|
229
|
+
# On Events - Scripts
|
230
|
+
# ---------------------------------------------------------------------
|
231
|
+
|
232
|
+
#
|
233
|
+
# Run the on render script if there is one.
|
234
|
+
#
|
235
|
+
def run_on_start
|
236
|
+
o = find_child ON_START
|
237
|
+
return unless o
|
238
|
+
|
239
|
+
Gloo::Exec::Dispatch.message( @engine, 'run', o )
|
240
|
+
end
|
241
|
+
|
242
|
+
#
|
243
|
+
# Run the on rendered script if there is one.
|
244
|
+
#
|
245
|
+
def run_on_stop
|
246
|
+
o = find_child ON_STOP
|
247
|
+
return unless o
|
248
|
+
|
249
|
+
Gloo::Exec::Dispatch.message( @engine, 'run', o )
|
250
|
+
end
|
251
|
+
|
252
|
+
|
253
|
+
# ---------------------------------------------------------------------
|
254
|
+
# Pages and standard elements.
|
255
|
+
# ---------------------------------------------------------------------
|
256
|
+
|
257
|
+
#
|
258
|
+
# Get the pages container.
|
259
|
+
#
|
260
|
+
def pages_container
|
261
|
+
return find_child PAGES
|
262
|
+
end
|
263
|
+
|
264
|
+
#
|
265
|
+
# Get the home page, the root/default route.
|
266
|
+
#
|
267
|
+
def home_page
|
268
|
+
o = find_child HOME
|
269
|
+
return nil unless o
|
270
|
+
|
271
|
+
o = Gloo::Objs::Alias.resolve_alias( @engine, o )
|
272
|
+
return o
|
273
|
+
end
|
274
|
+
|
275
|
+
#
|
276
|
+
# Get the application error page.
|
277
|
+
#
|
278
|
+
def err_page
|
279
|
+
o = find_child ERR_PAGE
|
280
|
+
return nil unless o
|
281
|
+
|
282
|
+
o = Gloo::Objs::Alias.resolve_alias( @engine, o )
|
283
|
+
return o
|
284
|
+
end
|
285
|
+
|
286
|
+
#
|
287
|
+
# Get the default layout for pages.
|
288
|
+
#
|
289
|
+
def default_layout
|
290
|
+
o = find_child LAYOUT
|
291
|
+
return nil unless o
|
292
|
+
|
293
|
+
o = Gloo::Objs::Alias.resolve_alias( @engine, o )
|
294
|
+
return o
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
data/lib/gloo/verbs/cls.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# Redirect the web svr request to a different page.
|
5
|
+
# This verb only works in context of a running web server.
|
6
|
+
#
|
7
|
+
|
8
|
+
module Gloo
|
9
|
+
module Verbs
|
10
|
+
class Redirect < Gloo::Core::Verb
|
11
|
+
|
12
|
+
KEYWORD = 'redirect'.freeze
|
13
|
+
KEYWORD_SHORT = 'go'.freeze
|
14
|
+
|
15
|
+
MISSING_EXPR_ERR = 'Missing Expression!'.freeze
|
16
|
+
|
17
|
+
#
|
18
|
+
# Run the verb.
|
19
|
+
#
|
20
|
+
def run
|
21
|
+
if @tokens.token_count < 2
|
22
|
+
@engine.err MISSING_EXPR_ERR
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
# Send the redirect page to the running app.
|
27
|
+
if @engine.app_running?
|
28
|
+
obj_name = @tokens.second
|
29
|
+
pn = Gloo::Core::Pn.new( @engine, obj_name )
|
30
|
+
@engine.running_app.obj.redirect = pn.resolve
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Get the Verb's keyword.
|
36
|
+
#
|
37
|
+
def self.keyword
|
38
|
+
return KEYWORD
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Get the Verb's keyword shortcut.
|
43
|
+
#
|
44
|
+
def self.keyword_shortcut
|
45
|
+
return KEYWORD_SHORT
|
46
|
+
end
|
47
|
+
|
48
|
+
# ---------------------------------------------------------------------
|
49
|
+
# Private functions
|
50
|
+
# ---------------------------------------------------------------------
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,194 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 20124 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# A helper class for static assets.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Gloo
|
8
|
+
module WebSvr
|
9
|
+
class Asset
|
10
|
+
|
11
|
+
ASSETS_FOLDER = 'assets'.freeze
|
12
|
+
IMAGES_FOLDER = 'images'.freeze
|
13
|
+
STYLESHEETS_FOLDER = 'stylesheets'.freeze
|
14
|
+
|
15
|
+
CSS_TYPE = 'text/css'.freeze
|
16
|
+
JS_TYPE = 'text/javascript'.freeze
|
17
|
+
|
18
|
+
IMAGE_TYPE = 'image/'.freeze
|
19
|
+
FAVICON_TYPE = 'image/x-icon'.freeze
|
20
|
+
|
21
|
+
|
22
|
+
# ---------------------------------------------------------------------
|
23
|
+
# Initialization
|
24
|
+
# ---------------------------------------------------------------------
|
25
|
+
|
26
|
+
#
|
27
|
+
# Set up the web server.
|
28
|
+
#
|
29
|
+
def initialize( engine, web_svr_obj )
|
30
|
+
@engine = engine
|
31
|
+
@log = @engine.log
|
32
|
+
|
33
|
+
@web_svr_obj = web_svr_obj
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# ---------------------------------------------------------------------
|
38
|
+
# Asset Helpers
|
39
|
+
# ---------------------------------------------------------------------
|
40
|
+
|
41
|
+
#
|
42
|
+
# Get the asset folder in the project.
|
43
|
+
#
|
44
|
+
def assets_folder
|
45
|
+
return File.join( @engine.settings.project_path, ASSETS_FOLDER )
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Get the images folder in the project.
|
50
|
+
#
|
51
|
+
def images_folder
|
52
|
+
return File.join( assets_folder, IMAGES_FOLDER )
|
53
|
+
end
|
54
|
+
|
55
|
+
#
|
56
|
+
# Get the stylesheets folder in the project.
|
57
|
+
#
|
58
|
+
def stylesheets_folder
|
59
|
+
return File.join( assets_folder, STYLESHEETS_FOLDER )
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# Find and return the page for the given route.
|
64
|
+
#
|
65
|
+
def path_for_file file
|
66
|
+
pn = file.value
|
67
|
+
|
68
|
+
# Is the file's value a recognizable file?
|
69
|
+
return pn if File.exist? pn
|
70
|
+
|
71
|
+
# Look in the web server's asset folder.
|
72
|
+
pn = File.join( assets_folder, pn )
|
73
|
+
|
74
|
+
return pn
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Get the return type for the given file.
|
79
|
+
#
|
80
|
+
def type_for_file file
|
81
|
+
ext = File.extname( file ).downcase
|
82
|
+
ext = ext[1..-1] if ext[0] == '.'
|
83
|
+
|
84
|
+
if ext == 'css'
|
85
|
+
return CSS_TYPE
|
86
|
+
elsif ext == 'js'
|
87
|
+
return JS_TYPE
|
88
|
+
elsif ext == 'ico'
|
89
|
+
return FAVICON_TYPE
|
90
|
+
else
|
91
|
+
return "#{IMAGE_TYPE}#{ext}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
# ---------------------------------------------------------------------
|
97
|
+
# Render Asset
|
98
|
+
# ---------------------------------------------------------------------
|
99
|
+
|
100
|
+
#
|
101
|
+
# Helper to create a successful image response with the given data.
|
102
|
+
#
|
103
|
+
def render_file( file )
|
104
|
+
type = type_for_file file
|
105
|
+
data = File.binread file
|
106
|
+
code = Gloo::WebSvr::ResponseCode::SUCCESS
|
107
|
+
|
108
|
+
return Gloo::WebSvr::Response.new( @engine, code, type, data )
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
# ---------------------------------------------------------------------
|
113
|
+
# Dynamic Add Assets
|
114
|
+
# ---------------------------------------------------------------------
|
115
|
+
|
116
|
+
#
|
117
|
+
# Add all asssets to the web server pages (routes).
|
118
|
+
#
|
119
|
+
def add_asset_routes
|
120
|
+
return unless File.exist? assets_folder
|
121
|
+
|
122
|
+
@log.debug 'Adding asset routes to web server…'
|
123
|
+
@factory = @engine.factory
|
124
|
+
|
125
|
+
add_containers
|
126
|
+
add_images
|
127
|
+
add_stylesheets
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
# Create the containers for the assets if they do not exist.
|
132
|
+
#
|
133
|
+
def add_containers
|
134
|
+
pages = @web_svr_obj.pages_container
|
135
|
+
|
136
|
+
@assets = pages.find_child( ASSETS_FOLDER ) ||
|
137
|
+
@factory.create_can( ASSETS_FOLDER, pages )
|
138
|
+
|
139
|
+
@images = @assets.find_child( IMAGES_FOLDER ) ||
|
140
|
+
@factory.create_can( IMAGES_FOLDER, @assets )
|
141
|
+
|
142
|
+
@stylesheets = @assets.find_child( STYLESHEETS_FOLDER ) ||
|
143
|
+
@factory.create_can( STYLESHEETS_FOLDER, @assets )
|
144
|
+
end
|
145
|
+
|
146
|
+
#
|
147
|
+
# Add the images to the web server pages.
|
148
|
+
#
|
149
|
+
def add_images
|
150
|
+
@log.debug 'Adding image asset routes to web server…'
|
151
|
+
|
152
|
+
return unless File.exist? images_folder
|
153
|
+
|
154
|
+
# for each file in the images folder
|
155
|
+
# create a file object and add it to the images container
|
156
|
+
Dir.each_child( images_folder ) do |name|
|
157
|
+
pn = File.join( IMAGES_FOLDER, name )
|
158
|
+
add_file_obj( @images, name, pn )
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
#
|
163
|
+
# Add the stylesheets to the web server pages.
|
164
|
+
#
|
165
|
+
def add_stylesheets
|
166
|
+
@log.debug 'Adding stylesheet asset routes to web server…'
|
167
|
+
|
168
|
+
return unless File.exist? stylesheets_folder
|
169
|
+
|
170
|
+
# for each file in the stylesheets folder
|
171
|
+
# create a file object and add it to the stylesheets container
|
172
|
+
Dir.each_child( stylesheets_folder ) do |name|
|
173
|
+
pn = File.join( STYLESHEETS_FOLDER, name )
|
174
|
+
add_file_obj( @stylesheets, name, pn )
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
#
|
179
|
+
# Add a file object (page route) to the given container.
|
180
|
+
#
|
181
|
+
def add_file_obj( can, name, pn )
|
182
|
+
name = name.gsub( '.', '_' )
|
183
|
+
@log.debug "Adding route for file: #{name}"
|
184
|
+
|
185
|
+
# First make sure the child doesn't already exist.
|
186
|
+
child = can.find_child( name )
|
187
|
+
return if child
|
188
|
+
|
189
|
+
@factory.create_file( name, pn, can )
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 20124 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# Configuration for a gloo web server.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Gloo
|
8
|
+
module WebSvr
|
9
|
+
class Config
|
10
|
+
|
11
|
+
SCHEME_SEPARATOR = '://'
|
12
|
+
HTTP = 'http'
|
13
|
+
HTTPS = 'https'
|
14
|
+
LOCALHOST = 'localhost'
|
15
|
+
PORT_DEFAULT = '8080'
|
16
|
+
|
17
|
+
attr_reader :scheme, :host, :port
|
18
|
+
|
19
|
+
|
20
|
+
# ---------------------------------------------------------------------
|
21
|
+
# Initialization
|
22
|
+
# ---------------------------------------------------------------------
|
23
|
+
|
24
|
+
#
|
25
|
+
# Set up the web server.
|
26
|
+
#
|
27
|
+
def initialize( scheme = HTTP, host = LOCALHOST, port = PORT_DEFAULT )
|
28
|
+
@scheme = scheme
|
29
|
+
@host = host
|
30
|
+
@port = port
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
# ---------------------------------------------------------------------
|
35
|
+
# Static Helper Functions
|
36
|
+
# ---------------------------------------------------------------------
|
37
|
+
|
38
|
+
|
39
|
+
# ---------------------------------------------------------------------
|
40
|
+
# Helper Functions
|
41
|
+
# ---------------------------------------------------------------------
|
42
|
+
|
43
|
+
#
|
44
|
+
# The base url, including scheme, host and port.
|
45
|
+
#
|
46
|
+
def base_url
|
47
|
+
url = "#{self.scheme}#{SCHEME_SEPARATOR}#{self.host}"
|
48
|
+
unless self.port.blank?
|
49
|
+
url << ":#{self.port}"
|
50
|
+
end
|
51
|
+
return url
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 20124 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# A helper class used to render parameters (ERB) in text.
|
5
|
+
# Also uses helper functions to render.
|
6
|
+
#
|
7
|
+
|
8
|
+
module Gloo
|
9
|
+
module WebSvr
|
10
|
+
class EmbeddedRenderer
|
11
|
+
|
12
|
+
HELPER = 'helper'.freeze
|
13
|
+
|
14
|
+
attr_reader :engine, :log, :web_svr_obj
|
15
|
+
|
16
|
+
|
17
|
+
# ---------------------------------------------------------------------
|
18
|
+
# Initialization
|
19
|
+
# ---------------------------------------------------------------------
|
20
|
+
|
21
|
+
#
|
22
|
+
# Set up the web server.
|
23
|
+
#
|
24
|
+
def initialize( engine, web_svr_obj )
|
25
|
+
@engine = engine
|
26
|
+
@log = @engine.log
|
27
|
+
|
28
|
+
@web_svr_obj = web_svr_obj
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# ---------------------------------------------------------------------
|
33
|
+
# Obj Helper Functions
|
34
|
+
# ---------------------------------------------------------------------
|
35
|
+
|
36
|
+
#
|
37
|
+
# Handle a missing method by looking for a helper function.
|
38
|
+
# If there is one, then call it and return the result.
|
39
|
+
# If not, log an error and return nil.
|
40
|
+
#
|
41
|
+
def method_missing( method_name, *args )
|
42
|
+
@log.debug "missing method '#{method_name}' with args #{args}"
|
43
|
+
|
44
|
+
helper_pn = "#{HELPER}.#{method_name}"
|
45
|
+
@log.debug "looking for function: #{helper_pn}"
|
46
|
+
|
47
|
+
pn = Gloo::Core::Pn.new( @engine, helper_pn )
|
48
|
+
obj = pn.resolve
|
49
|
+
if obj
|
50
|
+
@log.debug "found obj: #{obj.pn}"
|
51
|
+
return obj.invoke args
|
52
|
+
else
|
53
|
+
@log.error "Function not found: #{helper_pn}"
|
54
|
+
end
|
55
|
+
|
56
|
+
return nil
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# ---------------------------------------------------------------------
|
61
|
+
# Renderer
|
62
|
+
# ---------------------------------------------------------------------
|
63
|
+
|
64
|
+
#
|
65
|
+
# Render content with the given params.
|
66
|
+
# Params might be nil, in which case the content
|
67
|
+
# is returned with no changes.
|
68
|
+
#
|
69
|
+
def render content, params
|
70
|
+
# If the params is nil, let's make it an empty hash.
|
71
|
+
params = {} unless params
|
72
|
+
|
73
|
+
# Get the binding context for this render.
|
74
|
+
b = binding
|
75
|
+
|
76
|
+
# Add the params to the binding context.
|
77
|
+
params.each_pair do |key, value|
|
78
|
+
b.local_variable_set key.to_sym, value
|
79
|
+
end
|
80
|
+
|
81
|
+
# Render in the current binding content.
|
82
|
+
renderer = ERB.new( content )
|
83
|
+
content = renderer.result( b )
|
84
|
+
|
85
|
+
return content
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|