short_stack 0.1.1
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.
- data/.document +5 -0
- data/.gitignore +24 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +71 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +26 -0
- data/VERSION +1 -0
- data/lib/pancake/generators/global.rb +2 -0
- data/lib/pancake/generators/micro_generator.rb +23 -0
- data/lib/pancake/generators/short_generator.rb +23 -0
- data/lib/pancake/generators/templates/common/Gemfile +7 -0
- data/lib/pancake/generators/templates/common/dotgitignore +22 -0
- data/lib/pancake/generators/templates/common/dothtaccess +17 -0
- data/lib/pancake/generators/templates/micro/%stack_name%/%stack_name%.rb.tt +9 -0
- data/lib/pancake/generators/templates/micro/%stack_name%/Rakefile.tt +40 -0
- data/lib/pancake/generators/templates/micro/%stack_name%/config.ru.tt +15 -0
- data/lib/pancake/generators/templates/micro/%stack_name%/pancake_init.rb.tt +1 -0
- data/lib/pancake/generators/templates/micro/%stack_name%/public/.empty_directory +0 -0
- data/lib/pancake/generators/templates/micro/%stack_name%/tmp/.empty_directory +0 -0
- data/lib/pancake/generators/templates/micro/%stack_name%/views/layouts/application.html.haml +5 -0
- data/lib/pancake/generators/templates/micro/%stack_name%/views/root.html.haml +1 -0
- data/lib/pancake/generators/templates/short/%stack_name%/LICENSE.tt +20 -0
- data/lib/pancake/generators/templates/short/%stack_name%/README.tt +7 -0
- data/lib/pancake/generators/templates/short/%stack_name%/Rakefile.tt +56 -0
- data/lib/pancake/generators/templates/short/%stack_name%/VERSION.tt +1 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%.rb.tt +14 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/%stack_name%.rb.tt +6 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/config.ru.tt +11 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/config/config.rb.tt +23 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/config/environments/development.rb.tt +15 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/config/environments/production.rb.tt +16 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/config/environments/staging.rb.tt +15 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/models/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/mounts/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/public/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/tasks/%stack_name%.rake.tt +4 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/tmp/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/views/layouts/application.html.haml +5 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/views/root.html.haml +2 -0
- data/lib/pancake/generators/templates/short/%stack_name%/pancake_init.rb.tt +1 -0
- data/lib/pancake/generators/templates/short/%stack_name%/spec/%stack_name%_spec.rb.tt +11 -0
- data/lib/pancake/generators/templates/short/%stack_name%/spec/spec_helper.rb.tt +13 -0
- data/lib/short_stack.rb +213 -0
- data/lib/short_stack/controller.rb +185 -0
- data/lib/short_stack/default/views/base.html.haml +5 -0
- data/lib/short_stack/default/views/error.html.haml +12 -0
- data/lib/short_stack/middleware.rb +14 -0
- data/short_stack.gemspec +38 -0
- data/spec/fixtures/foobar/other_root/views/base.html.haml +4 -0
- data/spec/fixtures/foobar/views/basic.html.haml +1 -0
- data/spec/fixtures/foobar/views/inherited_from_base.html.haml +5 -0
- data/spec/fixtures/foobar/views/template.html.haml +3 -0
- data/spec/fixtures/foobar/views/vault.html.haml +3 -0
- data/spec/short_stack/controller_spec.rb +444 -0
- data/spec/short_stack/middlewares_spec.rb +14 -0
- data/spec/short_stack/router_spec.rb +153 -0
- data/spec/short_stack/short_stack_spec.rb +122 -0
- data/spec/short_stack/stack_spec.rb +124 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +13 -0
- metadata +181 -0
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'short_stack'
|
2
|
+
require 'haml'
|
3
|
+
|
4
|
+
class <%= ActiveSupport::Inflector.camelize(stack_name) %> < ShortStack
|
5
|
+
add_root(__FILE__, "<%= stack_name %>")
|
6
|
+
|
7
|
+
# Hook to use before we mount any applications
|
8
|
+
# before_mount_applications do
|
9
|
+
# end
|
10
|
+
|
11
|
+
initialize_stack
|
12
|
+
end
|
13
|
+
|
14
|
+
require ::File.join(Pancake.get_root(__FILE__, "<%= stack_name %>"), "<%= stack_name %>")
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'pancake'
|
2
|
+
require ::File.join(::File.expand_path(::File.dirname(__FILE__)), "..", "<%= stack_name %>")
|
3
|
+
|
4
|
+
# get the application to run. The application in the Pancake.start block
|
5
|
+
# is the master application. It will have all requests directed to it through the
|
6
|
+
# pancake middleware
|
7
|
+
# This should be a very minimal file, but should be used when any stand alone code needs to be included
|
8
|
+
<%= ActiveSupport::Inflector.camelize(stack_name) %>.include_pancake_stack!
|
9
|
+
app = Pancake.start(:root => Pancake.get_root(__FILE__)){ <%= ActiveSupport::Inflector.camelize(stack_name) %>.stackup(:master => true) }
|
10
|
+
|
11
|
+
run app
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Enter any global configuration for the stack in this file.
|
2
|
+
<% klass_name = ActiveSupport::Inflector.camelize(stack_name) %>
|
3
|
+
class <%= klass_name %>
|
4
|
+
# include middleware for the development stack
|
5
|
+
# Labels can be set in the config/environments/<env>.rb file to limit
|
6
|
+
# middleware loading.
|
7
|
+
# stack(:middleware_name, :labels => [:development, :production]).use(MiddlewareClass)
|
8
|
+
|
9
|
+
class self::Configuration
|
10
|
+
# Add defaults to your stack configuration.
|
11
|
+
# This is scoped to this stack, and is inhertied into child stacks
|
12
|
+
#
|
13
|
+
# Fixed value defaults:
|
14
|
+
# default :var_name, :value, "A description of the variable"
|
15
|
+
#
|
16
|
+
# Lazy Defaults:
|
17
|
+
# default :var_name, lambda{ configuration_method }, "Some Description"
|
18
|
+
|
19
|
+
# Declare methods on your configuraiton
|
20
|
+
# def configuration_method; #stuff; end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Pancake.logger.info "Loading Development Environment"
|
2
|
+
|
3
|
+
# Pancake.handle_errors!(true) # uncomment to have the stack handle any errors that occur
|
4
|
+
|
5
|
+
class <%= ActiveSupport::Inflector.camelize(stack_name) %>
|
6
|
+
# include middleware for the development stack
|
7
|
+
# stack(:middleware_name).use(MiddlewareClass)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Add code to hooks. Default available hooks:
|
11
|
+
# :before_build_stack, :before_mount_applications, :after_initialize_application, :after_build_stack
|
12
|
+
|
13
|
+
# <%= ActiveSupport::Inflector.camelize(stack_name) %>.before_build_stack do
|
14
|
+
# # stuff to do
|
15
|
+
# end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Pancake.logger.info "Loading Production Environment"
|
2
|
+
|
3
|
+
Pancake.handle_errors!(true) # uncomment to have the stack handle any errors that occur
|
4
|
+
<% klass_name = ActiveSupport::Inflector.camelize(stack_name) %>
|
5
|
+
class <%= klass_name %>
|
6
|
+
# include middleware for the development stack
|
7
|
+
# stack(:middleware_name).use(MiddlewareClass)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Add code to hooks. Default available hooks:
|
11
|
+
# :before_build_stack, :before_mount_applications, :after_initialize_application, :after_build_stack
|
12
|
+
|
13
|
+
# <%= klass_name %>.before_build_stack do
|
14
|
+
# # stuff to do
|
15
|
+
# end
|
16
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Pancake.logger.info "Loading Staging Environment"
|
2
|
+
|
3
|
+
Pancake.handle_errors!(true) # uncomment to have the stack handle any errors that occur
|
4
|
+
<% klass_name = ActiveSupport::Inflector.camelize(stack_name) %>
|
5
|
+
class <%= klass_name %>
|
6
|
+
# include middleware for the development stack
|
7
|
+
# stack(:middleware_name).use(MiddlewareClass)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Add code to hooks. Default available hooks:
|
11
|
+
# :before_build_stack, :before_mount_applications, :after_initialize_application, :after_build_stack
|
12
|
+
|
13
|
+
# <%= klass_name %>.before_build_stack do
|
14
|
+
# # stuff to do
|
15
|
+
# end
|
data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/models/.empty_directory
ADDED
File without changes
|
data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/mounts/.empty_directory
ADDED
File without changes
|
data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/public/.empty_directory
ADDED
File without changes
|
data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/tmp/.empty_directory
ADDED
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
require ::File.join(::File.expand_path(::File.dirname(__FILE__)), "lib", "<%= stack_name %>")
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require ::File.expand_path(::File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe <%= ActiveSupport::Inflector.camelize(stack_name) %> do
|
4
|
+
def app
|
5
|
+
<%= stack_name %>.stackup
|
6
|
+
end
|
7
|
+
|
8
|
+
it "fails" do
|
9
|
+
fail "hey buddy, you should probably rename this file and start specing for real"
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require 'rack/test'
|
3
|
+
require 'pancake'
|
4
|
+
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
8
|
+
require '<%= stack_name -%>'
|
9
|
+
|
10
|
+
Spec::Runner.configure do |config|
|
11
|
+
config.include(Rack::Test::Methods)
|
12
|
+
config.include(Pancake::Test::Matchers)
|
13
|
+
end
|
data/lib/short_stack.rb
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
require 'pancake'
|
2
|
+
require 'short_stack/middleware'
|
3
|
+
require 'short_stack/controller'
|
4
|
+
|
5
|
+
class ShortStack < Pancake::Stack
|
6
|
+
add_root(__FILE__, "short_stack/default")
|
7
|
+
|
8
|
+
push_paths(:models,"models", "**/*.rb")
|
9
|
+
|
10
|
+
# Make sure that the stack has been initialized
|
11
|
+
# Before we inherit any children.
|
12
|
+
# Otherwise they might not be loaded yet
|
13
|
+
before_inner_class_inheritance do |parent|
|
14
|
+
parent.initialize_stack
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.new_endpoint_instance
|
18
|
+
self::Controller
|
19
|
+
end
|
20
|
+
|
21
|
+
# Marks a method as published.
|
22
|
+
# This is done implicitly when using the get, post, put, delete methods on a Stacks::Short
|
23
|
+
# But can be done explicitly
|
24
|
+
#
|
25
|
+
# @see Pancake::Mixins::Publish#publish
|
26
|
+
# @api public
|
27
|
+
def self.publish(*args)
|
28
|
+
@published = true
|
29
|
+
self::Controller.publish(*args)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @see Pancake::Mixins::Publish#as
|
33
|
+
def self.as(*args)
|
34
|
+
self::Controller.as(*args)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @see Pancake::Mixins::Publish#provides
|
38
|
+
def self.provides(*formats)
|
39
|
+
self::Controller.provides(*formats)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.handle_exception(*args, &block)
|
43
|
+
self::Controller.handle_exception(*args, &block)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.helpers(&blk)
|
47
|
+
m = Module.new(&blk)
|
48
|
+
self::Controller.class_eval{ include m }
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.template(*args)
|
52
|
+
self::Controller.template(*args)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.base_template_name
|
56
|
+
self::Controller.base_template_name
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# Gets a resource at a given path
|
61
|
+
#
|
62
|
+
# The block should finish with the final result of the action
|
63
|
+
#
|
64
|
+
# @param [String] path - a url path that conforms to Usher match path.
|
65
|
+
# @param block - the contents of the block are executed when the path is matched.
|
66
|
+
#
|
67
|
+
# @example
|
68
|
+
# get "/posts(/:year(/:month(/:date))" do
|
69
|
+
# # do stuff to get posts and render them
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# @see Usher
|
73
|
+
# @api public
|
74
|
+
# @author Daniel Neighman
|
75
|
+
def self.get(path, opts = {}, &block)
|
76
|
+
define_published_action(:get, path, opts, block)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Posts a resource to a given path
|
80
|
+
#
|
81
|
+
# The block should finish with the final result of the action
|
82
|
+
#
|
83
|
+
# @param [String] path - a url path that conforms to Usher match path.
|
84
|
+
# @param block - the contents of the block are executed when the path is matched.
|
85
|
+
#
|
86
|
+
# @example
|
87
|
+
# post "/posts" do
|
88
|
+
# # do stuff to post /posts and render them
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# @see Usher
|
92
|
+
# @api public
|
93
|
+
# @author Daniel Neighman
|
94
|
+
def self.post(path, opts = {}, &block)
|
95
|
+
define_published_action(:post, path, opts, block)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Puts a resource to a given path
|
99
|
+
#
|
100
|
+
# The block should finish with the final result of the action
|
101
|
+
#
|
102
|
+
# @param [String] path - a url path that conforms to Usher match path.
|
103
|
+
# @param block - the contents of the block are executed when the path is matched.
|
104
|
+
#
|
105
|
+
# @example
|
106
|
+
# put "/posts" do
|
107
|
+
# # do stuff to post /posts and render them
|
108
|
+
# end
|
109
|
+
#
|
110
|
+
# @see Usher
|
111
|
+
# @api public
|
112
|
+
# @author Daniel Neighman
|
113
|
+
def self.put(path, opts = {}, &block)
|
114
|
+
define_published_action(:put, path, opts, block)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Deletes the resource at a given path
|
118
|
+
#
|
119
|
+
# The block should finish with the final result of the action
|
120
|
+
#
|
121
|
+
# @param [String] path - a url path that conforms to Usher match path.
|
122
|
+
# @param block - the contents of the block are executed when the path is matched.
|
123
|
+
#
|
124
|
+
# @example
|
125
|
+
# delete "/posts/foo-is-post" do
|
126
|
+
# # do stuff to post foo-is-post and render the result
|
127
|
+
# end
|
128
|
+
#
|
129
|
+
# @see Usher
|
130
|
+
# @api public
|
131
|
+
# @author Daniel Neighman
|
132
|
+
def self.delete(path, opts = {}, &block)
|
133
|
+
define_published_action(:delete, path, opts, block)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Matches any method to the route
|
137
|
+
# @api public
|
138
|
+
def self.any(path, opts={}, &block)
|
139
|
+
define_published_action(:any, path, opts, block)
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
# Defines an action on the inner Controller class of this stack.
|
144
|
+
# Also sets it as published if it's not already published.
|
145
|
+
#
|
146
|
+
# @param [Symbol] method - a smbol specifying the HTTP method
|
147
|
+
# @param [String] path - a string specifying the path to map the url to
|
148
|
+
# @api private
|
149
|
+
# @author Daniel Neighman
|
150
|
+
def self.define_published_action(method, path, opts, block)
|
151
|
+
self::Controller.publish unless @published
|
152
|
+
@published = nil
|
153
|
+
|
154
|
+
action_name = controller_method_name(method,path)
|
155
|
+
attach_action(action_name, block)
|
156
|
+
attach_route(method, path, action_name, opts)
|
157
|
+
end
|
158
|
+
|
159
|
+
# Does the work of actually defining the action on the Controller Class
|
160
|
+
#
|
161
|
+
# @param [String] - the name of the method to create on the Controller class
|
162
|
+
# @api private
|
163
|
+
# @author Daniel Neighman
|
164
|
+
def self.attach_action(method_name, block)
|
165
|
+
self::Controller.class_eval do
|
166
|
+
define_method(method_name, &block)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# Supplies the path as a route to the stack router
|
171
|
+
#
|
172
|
+
# @param method [Symbol]
|
173
|
+
#
|
174
|
+
# @example
|
175
|
+
# attach_route(:get, "/foo/bar", "get__foo_bar")
|
176
|
+
#
|
177
|
+
# @api private
|
178
|
+
# @author Daniel Neighman
|
179
|
+
def self.attach_route(method, path, action_name, options)
|
180
|
+
name = options.delete(:name)
|
181
|
+
r = router.add(path, options)
|
182
|
+
r.send(method) unless method == :any
|
183
|
+
r.name(name) if name
|
184
|
+
r.to(:action => action_name)
|
185
|
+
r
|
186
|
+
end
|
187
|
+
|
188
|
+
# provides for methods of the following form on Controller
|
189
|
+
# :<method>_<sanitized_path>
|
190
|
+
#
|
191
|
+
# @param [Symbol] method - the HTTP method to look for
|
192
|
+
# @param [String] path - the url path expression to encode into the method name
|
193
|
+
#
|
194
|
+
# @return [String] - The actual controller method name to use for the action
|
195
|
+
#
|
196
|
+
# @api private
|
197
|
+
# @author Daniel Neighman
|
198
|
+
def self.controller_method_name(method, path)
|
199
|
+
"#{method}_#{sanitize_path(path)}"
|
200
|
+
end
|
201
|
+
|
202
|
+
# sanitizes a path so it's able to be used as a method name
|
203
|
+
#
|
204
|
+
# @param [String] path - the path to sanitize
|
205
|
+
#
|
206
|
+
# @return [String] the sanitized version of the path safe to use as a method name
|
207
|
+
# @api private
|
208
|
+
# @author Daniel Neighman
|
209
|
+
def self.sanitize_path(path)
|
210
|
+
path.gsub(/\W/, "_")
|
211
|
+
end
|
212
|
+
end # ShortStack
|
213
|
+
|
@@ -0,0 +1,185 @@
|
|
1
|
+
class ShortStack < Pancake::Stack
|
2
|
+
inheritable_inner_classes :Controller
|
3
|
+
|
4
|
+
class Controller
|
5
|
+
extend Pancake::Mixins::Publish
|
6
|
+
include Pancake::Mixins::Render
|
7
|
+
include Pancake::Mixins::RequestHelper
|
8
|
+
include Pancake::Mixins::ResponseHelper
|
9
|
+
include Pancake::Mixins::StackHelper
|
10
|
+
|
11
|
+
inheritable_inner_classes :ViewContext
|
12
|
+
|
13
|
+
class self::ViewContext
|
14
|
+
include Pancake::Mixins::RequestHelper
|
15
|
+
include AnyView
|
16
|
+
|
17
|
+
# No way to get the env into the view context... this is not good :(
|
18
|
+
def env
|
19
|
+
_view_context_for.env
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.template(name_or_template, opts = {})
|
23
|
+
opts[:format] ||= content_type
|
24
|
+
super
|
25
|
+
end
|
26
|
+
|
27
|
+
def template(name_or_template, opts={})
|
28
|
+
opts[:format] ||= content_type
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
def _template_name_for(name, opts = {})
|
33
|
+
opts[:format] ||= :html
|
34
|
+
"#{name}.#{opts[:format]}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
extlib_inheritable_accessor :_handle_exception
|
39
|
+
|
40
|
+
push_paths(:views, ["app/views", "views"], "**/*")
|
41
|
+
|
42
|
+
DEFAULT_EXCEPTION_HANDLER = lambda do |error|
|
43
|
+
if layout = env['layout']
|
44
|
+
layout.content = render :error, :error => error
|
45
|
+
layout
|
46
|
+
else
|
47
|
+
render :error, :error => error
|
48
|
+
end
|
49
|
+
end unless defined?(DEFAULT_EXCEPTION_HANDLER)
|
50
|
+
|
51
|
+
# @api private
|
52
|
+
def self.call(env)
|
53
|
+
app = new(env)
|
54
|
+
app.dispatch!
|
55
|
+
end
|
56
|
+
|
57
|
+
def layout
|
58
|
+
env['layout']
|
59
|
+
end
|
60
|
+
|
61
|
+
# @api public
|
62
|
+
attr_accessor :status
|
63
|
+
|
64
|
+
def initialize(env)
|
65
|
+
@env, @request = env, Rack::Request.new(env)
|
66
|
+
@status = 200
|
67
|
+
end
|
68
|
+
|
69
|
+
# Provides access to the request params
|
70
|
+
# @api public
|
71
|
+
def params
|
72
|
+
request.params
|
73
|
+
end
|
74
|
+
|
75
|
+
attr_writer :action
|
76
|
+
def action
|
77
|
+
@action ||= begin
|
78
|
+
rr = request.env['router.response']
|
79
|
+
action = rr && rr.dest && rr.dest[:action]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Dispatches to an action based on the params["action"] parameter
|
84
|
+
def dispatch!
|
85
|
+
if logger
|
86
|
+
logger.info "Request: #{request.path}"
|
87
|
+
logger.info "Params: #{params.inspect}"
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
# Check that the action is available
|
92
|
+
raise Pancake::Errors::NotFound, "No Action Found" unless allowed_action?(action)
|
93
|
+
|
94
|
+
@action_opts = actions[action]
|
95
|
+
|
96
|
+
negotiate_content_type!(@action_opts.formats, params)
|
97
|
+
|
98
|
+
# Set the layout defaults before the action is rendered
|
99
|
+
if layout && stack_class.default_layout
|
100
|
+
layout.template_name = stack_class.default_layout
|
101
|
+
end
|
102
|
+
|
103
|
+
layout.format = params['format'] if layout
|
104
|
+
|
105
|
+
logger.info "Dispatching to #{action.inspect}" if logger
|
106
|
+
|
107
|
+
result = catch(:halt){ self.send(action) }
|
108
|
+
|
109
|
+
case result
|
110
|
+
when Array
|
111
|
+
result
|
112
|
+
when Rack::Response
|
113
|
+
result.finish
|
114
|
+
when String
|
115
|
+
out = if layout
|
116
|
+
layout.content = result
|
117
|
+
layout
|
118
|
+
else
|
119
|
+
result
|
120
|
+
end
|
121
|
+
Rack::Response.new(out, status, headers).finish
|
122
|
+
else
|
123
|
+
Rack::Response.new((result || ""), status, headers).finish
|
124
|
+
end
|
125
|
+
|
126
|
+
rescue Pancake::Errors::HttpError => e
|
127
|
+
if logger && log_http_error?(e)
|
128
|
+
logger.error "Exception: #{e.message}"
|
129
|
+
logger.error e.backtrace.join("\n")
|
130
|
+
end
|
131
|
+
handle_request_exception(e)
|
132
|
+
rescue Exception => e
|
133
|
+
if Pancake.handle_errors?
|
134
|
+
server_error = Pancake::Errors::Server.new(e.message)
|
135
|
+
server_error.exceptions << e
|
136
|
+
server_error.set_backtrace e.backtrace
|
137
|
+
else
|
138
|
+
server_error = e
|
139
|
+
end
|
140
|
+
handle_request_exception(server_error)
|
141
|
+
end
|
142
|
+
|
143
|
+
def log_http_error?(error)
|
144
|
+
true
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.handle_exception(&block)
|
148
|
+
if block_given?
|
149
|
+
self._handle_exception = block
|
150
|
+
else
|
151
|
+
self._handle_exception || DEFAULT_EXCEPTION_HANDLER
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def handle_request_exception(error)
|
156
|
+
raise(error.class, error.message, error.backtrace) unless Pancake.handle_errors?
|
157
|
+
self.status = error.code
|
158
|
+
result = instance_exec error, &self.class.handle_exception
|
159
|
+
Rack::Response.new(result, status, headers).finish
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
def allowed_action?(action)
|
164
|
+
self.class.actions.include?(action.to_s)
|
165
|
+
end
|
166
|
+
|
167
|
+
public
|
168
|
+
def self.roots
|
169
|
+
stack_class.roots
|
170
|
+
end
|
171
|
+
|
172
|
+
def self._template_name_for(name, opts)
|
173
|
+
opts[:format] ||= :html
|
174
|
+
[
|
175
|
+
"#{name}.#{opts[:format]}",
|
176
|
+
"#{name}"
|
177
|
+
]
|
178
|
+
end
|
179
|
+
|
180
|
+
def _tempate_name_for(name, opts = {})
|
181
|
+
opts[:format] ||= content_type
|
182
|
+
self.class._template_name_for(name, opts)
|
183
|
+
end
|
184
|
+
end # Controller
|
185
|
+
end # Short
|