utopia 1.7.1 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -3
- data/README.md +142 -11
- data/benchmarks/string_vs_symbol.rb +12 -0
- data/lib/utopia/command.rb +16 -13
- data/lib/utopia/content.rb +1 -5
- data/lib/utopia/content/node.rb +9 -4
- data/lib/utopia/{extensions/rack.rb → content/response.rb} +33 -30
- data/lib/utopia/content/tag.rb +14 -17
- data/lib/utopia/content/transaction.rb +19 -17
- data/lib/utopia/controller.rb +29 -8
- data/lib/utopia/controller/actions.rb +148 -0
- data/lib/utopia/controller/base.rb +9 -49
- data/lib/utopia/controller/respond.rb +1 -1
- data/lib/utopia/controller/rewrite.rb +9 -1
- data/lib/utopia/controller/variables.rb +1 -0
- data/lib/utopia/localization.rb +4 -1
- data/lib/utopia/middleware.rb +0 -2
- data/lib/utopia/path.rb +9 -0
- data/lib/utopia/path/matcher.rb +0 -1
- data/lib/utopia/redirection.rb +3 -2
- data/lib/utopia/session.rb +119 -2
- data/lib/utopia/session/lazy_hash.rb +1 -3
- data/lib/utopia/setup.rb +73 -0
- data/lib/utopia/static.rb +9 -2
- data/lib/utopia/version.rb +1 -1
- data/setup/examples/wiki/controller.rb +41 -0
- data/setup/examples/wiki/edit.xnode +15 -0
- data/setup/examples/wiki/index.xnode +10 -0
- data/setup/examples/wiki/welcome/content.md +3 -0
- data/setup/server/config/environment.yaml +1 -0
- data/setup/server/git/hooks/post-receive +4 -5
- data/setup/site/Gemfile +5 -0
- data/setup/site/config.ru +2 -1
- data/setup/site/config/environment.rb +5 -17
- data/setup/site/pages/_page.xnode +4 -2
- data/setup/site/pages/links.yaml +1 -1
- data/setup/site/pages/welcome/index.xnode +33 -15
- data/setup/site/public/_static/site.css +72 -4
- data/setup/site/tasks/utopia.rake +8 -0
- data/spec/utopia/{rack_spec.rb → content/response_spec.rb} +12 -19
- data/spec/utopia/content_spec.rb +2 -3
- data/spec/utopia/controller/{action_spec.rb → actions_spec.rb} +18 -32
- data/spec/utopia/controller/middleware_spec.rb +10 -10
- data/spec/utopia/controller/middleware_spec/controller/controller.rb +3 -3
- data/spec/utopia/controller/middleware_spec/controller/nested/controller.rb +1 -1
- data/spec/utopia/controller/middleware_spec/redirect/controller.rb +1 -1
- data/spec/utopia/controller/respond_spec.rb +3 -2
- data/spec/utopia/controller/respond_spec/api/controller.rb +2 -2
- data/spec/utopia/controller/respond_spec/errors/controller.rb +1 -1
- data/spec/utopia/controller/rewrite_spec.rb +1 -1
- data/spec/utopia/controller/sequence_spec.rb +12 -16
- data/spec/utopia/exceptions/handler_spec/controller.rb +2 -2
- data/spec/utopia/performance_spec/config.ru +1 -0
- data/spec/utopia/session_spec.rb +34 -1
- data/spec/utopia/session_spec.ru +3 -3
- data/spec/utopia/setup_spec.rb +2 -2
- data/utopia.gemspec +2 -2
- metadata +18 -12
- data/lib/utopia/controller/action.rb +0 -116
- data/lib/utopia/session/encrypted_cookie.rb +0 -118
data/lib/utopia/content/tag.rb
CHANGED
@@ -56,52 +56,49 @@ module Utopia
|
|
56
56
|
def [](key)
|
57
57
|
@attributes[key]
|
58
58
|
end
|
59
|
-
|
60
|
-
def to_html(content = nil, buffer = StringIO.new)
|
61
|
-
write_full_html(buffer, content)
|
62
|
-
|
63
|
-
return buffer.string
|
64
|
-
end
|
65
59
|
|
66
60
|
def to_hash
|
67
61
|
@attributes
|
68
62
|
end
|
69
63
|
|
70
64
|
def to_s(content = nil)
|
71
|
-
buffer =
|
65
|
+
buffer = String.new
|
66
|
+
|
72
67
|
write_full_html(buffer, content)
|
73
|
-
|
68
|
+
|
69
|
+
return buffer
|
74
70
|
end
|
75
71
|
|
72
|
+
alias to_html to_s
|
73
|
+
|
76
74
|
def write_open_html(buffer, terminate = false)
|
77
|
-
buffer
|
78
|
-
buffer.write "<#{name}"
|
75
|
+
buffer << "<#{name}"
|
79
76
|
|
80
77
|
@attributes.each do |key, value|
|
81
78
|
if value
|
82
|
-
buffer
|
79
|
+
buffer << " #{key}=\"#{value}\""
|
83
80
|
else
|
84
|
-
buffer
|
81
|
+
buffer << " #{key}"
|
85
82
|
end
|
86
83
|
end
|
87
84
|
|
88
85
|
if terminate
|
89
|
-
buffer
|
86
|
+
buffer << "/>"
|
90
87
|
else
|
91
|
-
buffer
|
88
|
+
buffer << ">"
|
92
89
|
end
|
93
90
|
end
|
94
91
|
|
95
92
|
def write_close_html(buffer)
|
96
|
-
buffer
|
93
|
+
buffer << "</#{name}>"
|
97
94
|
end
|
98
95
|
|
99
96
|
def write_full_html(buffer, content = nil)
|
100
|
-
if @closed
|
97
|
+
if @closed and content.nil?
|
101
98
|
write_open_html(buffer, true)
|
102
99
|
else
|
103
100
|
write_open_html(buffer)
|
104
|
-
buffer
|
101
|
+
buffer << content if content
|
105
102
|
write_close_html(buffer)
|
106
103
|
end
|
107
104
|
end
|
@@ -20,6 +20,8 @@
|
|
20
20
|
|
21
21
|
require_relative 'links'
|
22
22
|
|
23
|
+
require_relative 'response'
|
24
|
+
|
23
25
|
module Utopia
|
24
26
|
class Content
|
25
27
|
# This error is thrown if a tag doesn't match up when parsing the
|
@@ -37,19 +39,21 @@ module Utopia
|
|
37
39
|
CONTENT_TAG_NAME = "content".freeze
|
38
40
|
|
39
41
|
# A single request through content middleware. We use a struct to hide instance varibles since we instance_exec within this context.
|
40
|
-
class Transaction
|
41
|
-
|
42
|
-
|
43
|
-
def initialize(request, response, attributes = {})
|
42
|
+
class Transaction < Response
|
43
|
+
def initialize(request, attributes = {})
|
44
44
|
@request = request
|
45
|
-
@response = response
|
46
45
|
|
47
46
|
@attributes = attributes
|
48
47
|
|
49
48
|
@begin_tags = []
|
50
49
|
@end_tags = []
|
50
|
+
|
51
|
+
super()
|
51
52
|
end
|
52
53
|
|
54
|
+
attr :status
|
55
|
+
attr :headers
|
56
|
+
|
53
57
|
# A helper method for accessing controller variables from view:
|
54
58
|
def controller
|
55
59
|
@controller ||= Utopia::Controller[request]
|
@@ -66,9 +70,6 @@ module Utopia
|
|
66
70
|
# The Rack::Request for this transaction.
|
67
71
|
attr :request
|
68
72
|
|
69
|
-
# The mutable Rack::Response for this transaction.
|
70
|
-
attr :response
|
71
|
-
|
72
73
|
# Per-transaction global attributes.
|
73
74
|
attr :attributes
|
74
75
|
|
@@ -133,7 +134,6 @@ module Utopia
|
|
133
134
|
# Get the current tag which we are completing/ending:
|
134
135
|
top = current
|
135
136
|
|
136
|
-
|
137
137
|
if top.tags.empty?
|
138
138
|
if top.node.respond_to? :tag_end
|
139
139
|
top.node.tag_end(self, top)
|
@@ -156,7 +156,7 @@ module Utopia
|
|
156
156
|
|
157
157
|
return nil
|
158
158
|
end
|
159
|
-
|
159
|
+
|
160
160
|
def render_node(node, attributes = {})
|
161
161
|
self.begin_tags << State.new(attributes, node)
|
162
162
|
|
@@ -206,8 +206,10 @@ module Utopia
|
|
206
206
|
class Transaction::State
|
207
207
|
def initialize(tag, node, attributes = tag.to_hash)
|
208
208
|
@node = node
|
209
|
-
|
210
|
-
|
209
|
+
|
210
|
+
# The contents of the output
|
211
|
+
@buffer = String.new
|
212
|
+
|
211
213
|
@overrides = {}
|
212
214
|
|
213
215
|
@tags = []
|
@@ -228,7 +230,7 @@ module Utopia
|
|
228
230
|
def defer(value = nil, &block)
|
229
231
|
@deferred << block
|
230
232
|
|
231
|
-
Tag.closed(DEFERRED_TAG_NAME, :id => @deferred.size - 1).
|
233
|
+
Tag.closed(DEFERRED_TAG_NAME, :id => @deferred.size - 1).to_s
|
232
234
|
end
|
233
235
|
|
234
236
|
def [](key)
|
@@ -250,8 +252,8 @@ module Utopia
|
|
250
252
|
end
|
251
253
|
|
252
254
|
def call(transaction)
|
253
|
-
@content = @buffer
|
254
|
-
@buffer =
|
255
|
+
@content = @buffer
|
256
|
+
@buffer = String.new
|
255
257
|
|
256
258
|
if node.respond_to? :call
|
257
259
|
node.call(transaction, self)
|
@@ -259,11 +261,11 @@ module Utopia
|
|
259
261
|
transaction.parse_markup(@content)
|
260
262
|
end
|
261
263
|
|
262
|
-
return @buffer
|
264
|
+
return @buffer
|
263
265
|
end
|
264
266
|
|
265
267
|
def cdata(text)
|
266
|
-
@buffer
|
268
|
+
@buffer << text
|
267
269
|
end
|
268
270
|
|
269
271
|
def markup(text)
|
data/lib/utopia/controller.rb
CHANGED
@@ -22,15 +22,16 @@ require_relative 'path'
|
|
22
22
|
|
23
23
|
require_relative 'middleware'
|
24
24
|
require_relative 'controller/variables'
|
25
|
-
require_relative 'controller/action'
|
26
25
|
require_relative 'controller/base'
|
27
26
|
|
28
27
|
require_relative 'controller/rewrite'
|
29
28
|
require_relative 'controller/respond'
|
29
|
+
require_relative 'controller/actions'
|
30
30
|
|
31
31
|
require 'concurrent/map'
|
32
32
|
|
33
33
|
module Utopia
|
34
|
+
# A container for controller classes which are loaded from disk.
|
34
35
|
module Controllers
|
35
36
|
def self.class_name_for_controller(controller)
|
36
37
|
controller.uri_path.to_a.collect{|_| _.capitalize}.join + "_#{controller.object_id}"
|
@@ -44,14 +45,16 @@ module Utopia
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
48
|
+
# A middleware which loads controller classes and invokes functionality based on the requested path.
|
47
49
|
class Controller
|
50
|
+
# The controller filename.
|
48
51
|
CONTROLLER_RB = 'controller.rb'.freeze
|
49
52
|
|
50
53
|
def self.[] request
|
51
54
|
request.env[VARIABLES_KEY]
|
52
55
|
end
|
53
56
|
|
54
|
-
def initialize(app, root: nil, cache_controllers: false)
|
57
|
+
def initialize(app, root: nil, cache_controllers: false, base: nil)
|
55
58
|
@app = app
|
56
59
|
@root = root || Utopia::default_root
|
57
60
|
|
@@ -60,6 +63,10 @@ module Utopia
|
|
60
63
|
else
|
61
64
|
@controller_cache = nil
|
62
65
|
end
|
66
|
+
|
67
|
+
warn "Controller middleware is automatically prepending Actions! Will be deprecated in 2.x" if $VERBOSE and base.nil?
|
68
|
+
|
69
|
+
@base = base || Controller::Base.dup.prepend(Controller::Actions)
|
63
70
|
end
|
64
71
|
|
65
72
|
attr :app
|
@@ -67,9 +74,13 @@ module Utopia
|
|
67
74
|
def freeze
|
68
75
|
@root.freeze
|
69
76
|
|
77
|
+
# Should we freeze the base class?
|
78
|
+
# @base.freeze
|
79
|
+
|
70
80
|
super
|
71
81
|
end
|
72
82
|
|
83
|
+
# Fetch the controller for the given relative path. May be cached.
|
73
84
|
def lookup_controller(path)
|
74
85
|
if @controller_cache
|
75
86
|
@controller_cache.fetch_or_store(path.to_s) do
|
@@ -80,6 +91,7 @@ module Utopia
|
|
80
91
|
end
|
81
92
|
end
|
82
93
|
|
94
|
+
# Loads the controller file for the given relative url_path.
|
83
95
|
def load_controller_file(uri_path)
|
84
96
|
base_path = File.join(@root, uri_path.components)
|
85
97
|
|
@@ -87,7 +99,7 @@ module Utopia
|
|
87
99
|
# puts "load_controller_file(#{path.inspect}) => #{controller_path}"
|
88
100
|
|
89
101
|
if File.exist?(controller_path)
|
90
|
-
klass = Class.new(
|
102
|
+
klass = Class.new(@base)
|
91
103
|
|
92
104
|
# base_path is expected to be a string representing a filesystem path:
|
93
105
|
klass.const_set(:BASE_PATH, base_path.freeze)
|
@@ -112,13 +124,22 @@ module Utopia
|
|
112
124
|
end
|
113
125
|
end
|
114
126
|
|
127
|
+
# Invoke the controller layer for a given request. The request path may be rewritten.
|
115
128
|
def invoke_controllers(request)
|
116
|
-
|
129
|
+
request_path = Path.from_string(request.path_info)
|
130
|
+
|
131
|
+
# The request path must be absolute. We could handle this internally but it is probably better for this to be an error:
|
132
|
+
raise ArgumentError.new("Invalid request path #{request_path}") unless request_path.absolute?
|
133
|
+
|
134
|
+
# The controller path contains the current complete path being evaluated:
|
117
135
|
controller_path = Path.new
|
136
|
+
|
137
|
+
# Controller instance variables which eventually get processed by the view:
|
118
138
|
variables = request.env[VARIABLES_KEY]
|
119
139
|
|
120
|
-
while
|
121
|
-
|
140
|
+
while request_path.components.any?
|
141
|
+
# We copy one path component from the relative path to the controller path at a time. The controller, when invoked, can modify the relative path (by assigning to relative_path.components). This allows for controller-relative rewrites, but only the remaining path postfix can be modified.
|
142
|
+
controller_path.components << request_path.components.shift
|
122
143
|
|
123
144
|
if controller = lookup_controller(controller_path)
|
124
145
|
# Don't modify the original controller:
|
@@ -127,13 +148,13 @@ module Utopia
|
|
127
148
|
# Append the controller to the set of controller variables, updates the controller with all current instance variables.
|
128
149
|
variables << controller
|
129
150
|
|
130
|
-
if result = controller.process!(request,
|
151
|
+
if result = controller.process!(request, request_path)
|
131
152
|
return result
|
132
153
|
end
|
133
154
|
end
|
134
155
|
end
|
135
156
|
|
136
|
-
# The controllers may have rewriten the path so we update the path info:
|
157
|
+
# Controllers can directly modify relative_path, which is copied into controller_path. The controllers may have rewriten the path so we update the path info:
|
137
158
|
request.env[Rack::PATH_INFO] = controller_path.to_s
|
138
159
|
|
139
160
|
# No controller gave a useful result:
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# Copyright, 2016, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require_relative '../http'
|
22
|
+
|
23
|
+
module Utopia
|
24
|
+
class Controller
|
25
|
+
module Actions
|
26
|
+
def self.prepended(base)
|
27
|
+
base.extend(ClassMethods)
|
28
|
+
end
|
29
|
+
|
30
|
+
class Action < Hash
|
31
|
+
def initialize(options = {}, &block)
|
32
|
+
@options = options
|
33
|
+
@callback = block
|
34
|
+
|
35
|
+
super()
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_accessor :callback, :options
|
39
|
+
|
40
|
+
def callback?
|
41
|
+
@callback != nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def eql? other
|
45
|
+
super and @callback.eql? other.callback and @options.eql? other.options
|
46
|
+
end
|
47
|
+
|
48
|
+
def hash
|
49
|
+
[super, @callback, @options].hash
|
50
|
+
end
|
51
|
+
|
52
|
+
def == other
|
53
|
+
super and @callback == other.callback and @options == other.options
|
54
|
+
end
|
55
|
+
|
56
|
+
WILDCARD_GREEDY = '**'.freeze
|
57
|
+
WILDCARD = '*'.freeze
|
58
|
+
|
59
|
+
# Given a path, iterate over all actions that match. Actions match from most specific to most general.
|
60
|
+
# @return nil if nothing matched, or true if something matched.
|
61
|
+
def apply(path, index = -1, &block)
|
62
|
+
# ** is greedy, it always matches if possible and matches all remaining input.
|
63
|
+
if match_all = self[WILDCARD_GREEDY] and match_all.callback?
|
64
|
+
matched = true; yield(match_all)
|
65
|
+
end
|
66
|
+
|
67
|
+
if name = path[index]
|
68
|
+
# puts "Matching #{name} in #{self.keys.inspect}"
|
69
|
+
|
70
|
+
if match_name = self[name]
|
71
|
+
# puts "Matched against exact name #{name}: #{match_name}"
|
72
|
+
matched = match_name.apply(path, index-1, &block) || matched
|
73
|
+
end
|
74
|
+
|
75
|
+
if match_one = self[WILDCARD]
|
76
|
+
# puts "Match against #{WILDCARD}: #{match_one}"
|
77
|
+
matched = match_one.apply(path, index-1, &block) || matched
|
78
|
+
end
|
79
|
+
elsif self.callback?
|
80
|
+
# Got to end, matched completely:
|
81
|
+
matched = true; yield(self)
|
82
|
+
end
|
83
|
+
|
84
|
+
return matched
|
85
|
+
end
|
86
|
+
|
87
|
+
def matching(path, &block)
|
88
|
+
to_enum(:apply, path).to_a
|
89
|
+
end
|
90
|
+
|
91
|
+
def define(path, **options, &callback)
|
92
|
+
# puts "Defining path: #{path.inspect}"
|
93
|
+
current = self
|
94
|
+
|
95
|
+
path.reverse_each do |name|
|
96
|
+
current = (current[name] ||= Action.new)
|
97
|
+
end
|
98
|
+
|
99
|
+
current.options = options
|
100
|
+
current.callback = callback
|
101
|
+
|
102
|
+
return current
|
103
|
+
end
|
104
|
+
|
105
|
+
def inspect
|
106
|
+
if callback?
|
107
|
+
"<action " + super + ":#{callback.source_location}(#{options})>"
|
108
|
+
else
|
109
|
+
"<action " + super + ">"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
module ClassMethods
|
115
|
+
def actions
|
116
|
+
@actions ||= Action.new
|
117
|
+
end
|
118
|
+
|
119
|
+
def on(first, *path, **options, &block)
|
120
|
+
if first.is_a? Symbol
|
121
|
+
first = ['**', first.to_s]
|
122
|
+
end
|
123
|
+
|
124
|
+
actions.define(Path.split(first) + path, options, &block)
|
125
|
+
end
|
126
|
+
|
127
|
+
def dispatch(controller, request, path)
|
128
|
+
if @actions
|
129
|
+
@actions.apply(path.components) do |action|
|
130
|
+
controller.instance_exec(request, path, &action.callback)
|
131
|
+
end || controller.otherwise(request, path)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def otherwise(request, path)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Given a request, call associated actions if at least one exists.
|
140
|
+
def process!(request, path)
|
141
|
+
# puts "Actions\#process!(..., #{path.inspect})"
|
142
|
+
catch_response do
|
143
|
+
self.class.dispatch(self, request, path)
|
144
|
+
end || super
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -23,14 +23,17 @@ require_relative '../http'
|
|
23
23
|
module Utopia
|
24
24
|
class Controller
|
25
25
|
class Base
|
26
|
+
# A string which is the full path to the directory which contains the controller.
|
26
27
|
def self.base_path
|
27
28
|
self.const_get(:BASE_PATH)
|
28
29
|
end
|
29
|
-
|
30
|
+
|
31
|
+
# A relative path to the controller directory relative to the controller root directory.
|
30
32
|
def self.uri_path
|
31
33
|
self.const_get(:URI_PATH)
|
32
34
|
end
|
33
|
-
|
35
|
+
|
36
|
+
# The controller middleware itself.
|
34
37
|
def self.controller
|
35
38
|
self.const_get(:CONTROLLER)
|
36
39
|
end
|
@@ -48,32 +51,6 @@ module Utopia
|
|
48
51
|
def direct?(path)
|
49
52
|
path.dirname == uri_path
|
50
53
|
end
|
51
|
-
|
52
|
-
def actions
|
53
|
-
@actions ||= Action.new
|
54
|
-
end
|
55
|
-
|
56
|
-
def on(first, *path, **options, &block)
|
57
|
-
if first.is_a? Symbol
|
58
|
-
first = ['**', first]
|
59
|
-
end
|
60
|
-
|
61
|
-
actions.define(Path.split(first) + path, options, &block)
|
62
|
-
end
|
63
|
-
|
64
|
-
def lookup(path)
|
65
|
-
if @actions
|
66
|
-
relative_path = (path - uri_path).to_a
|
67
|
-
return @actions.select(relative_path)
|
68
|
-
else
|
69
|
-
[]
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
# Given a path, look up all matched actions.
|
75
|
-
def actions_for_request(request, path)
|
76
|
-
self.class.lookup(path)
|
77
54
|
end
|
78
55
|
|
79
56
|
def catch_response
|
@@ -82,18 +59,8 @@ module Utopia
|
|
82
59
|
end
|
83
60
|
end
|
84
61
|
|
85
|
-
#
|
86
|
-
def
|
87
|
-
actions = actions_for_request(request, path)
|
88
|
-
|
89
|
-
unless actions.empty?
|
90
|
-
return catch_response do
|
91
|
-
actions.each do |action|
|
92
|
-
action.call(self, request, path)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
62
|
+
# Return nil if this controller didn't do anything. Request will keep on processing. Return a valid rack response if the controller can do so.
|
63
|
+
def process!(request, relative_path)
|
97
64
|
return nil
|
98
65
|
end
|
99
66
|
|
@@ -114,7 +81,7 @@ module Utopia
|
|
114
81
|
throw :response, response
|
115
82
|
end
|
116
83
|
|
117
|
-
|
84
|
+
# This will cause the controller middleware to pass on the request.
|
118
85
|
def ignore!
|
119
86
|
throw :response, nil
|
120
87
|
end
|
@@ -140,6 +107,7 @@ module Utopia
|
|
140
107
|
respond! [status.to_i, {}, [message]]
|
141
108
|
end
|
142
109
|
|
110
|
+
# Succeed the request and immediately respond.
|
143
111
|
def succeed!(status: 200, headers: {}, **options)
|
144
112
|
status = HTTP::Status.new(status, 200...300)
|
145
113
|
|
@@ -159,14 +127,6 @@ module Utopia
|
|
159
127
|
return [content]
|
160
128
|
end
|
161
129
|
end
|
162
|
-
|
163
|
-
# Legacy method name:
|
164
|
-
alias success! succeed!
|
165
|
-
|
166
|
-
# Return nil if this controller didn't do anything. Request will keep on processing. Return a valid rack response if the controller can do so.
|
167
|
-
def process!(request, path)
|
168
|
-
passthrough(request, path)
|
169
|
-
end
|
170
130
|
end
|
171
131
|
end
|
172
132
|
end
|