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.
- checksums.yaml +4 -4
- data/gloo.gemspec +1 -0
- data/lib/VERSION +1 -1
- data/lib/VERSION_NOTES +6 -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 +1 -2
- 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
|