hassox-pancake 0.1.6
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/LICENSE +20 -0
- data/README.textile +95 -0
- data/Rakefile +56 -0
- data/TODO +18 -0
- data/bin/jeweler +19 -0
- data/bin/pancake-gen +17 -0
- data/bin/rubyforge +19 -0
- data/lib/pancake.rb +48 -0
- data/lib/pancake/bootloaders.rb +180 -0
- data/lib/pancake/configuration.rb +140 -0
- data/lib/pancake/core_ext/class.rb +44 -0
- data/lib/pancake/core_ext/object.rb +22 -0
- data/lib/pancake/core_ext/symbol.rb +15 -0
- data/lib/pancake/errors.rb +61 -0
- data/lib/pancake/generators.rb +8 -0
- data/lib/pancake/generators/base.rb +12 -0
- data/lib/pancake/generators/flat_generator.rb +17 -0
- data/lib/pancake/generators/short_generator.rb +17 -0
- data/lib/pancake/generators/stack_generator.rb +17 -0
- data/lib/pancake/generators/templates/common/dotgitignore +22 -0
- data/lib/pancake/generators/templates/common/dothtaccess +17 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/%stack_name%.rb.tt +8 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/.gitignore +21 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/config.ru.tt +12 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/pancake.init.tt +1 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/public/.empty_directory +0 -0
- data/lib/pancake/generators/templates/flat/%stack_name%/tmp/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/.gitignore +21 -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 +48 -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 +5 -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 +12 -0
- data/lib/pancake/generators/templates/short/%stack_name%/lib/%stack_name%/gems/cache/.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%/tmp/.empty_directory +0 -0
- data/lib/pancake/generators/templates/short/%stack_name%/pancake.init.tt +1 -0
- data/lib/pancake/generators/templates/short/%stack_name%/spec/%stack_name%_spec.rb.tt +7 -0
- data/lib/pancake/generators/templates/short/%stack_name%/spec/spec_helper.rb.tt +9 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/.gitignore +21 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/LICENSE.tt +20 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/README.tt +7 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/Rakefile.tt +48 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/VERSION.tt +1 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%.rb.tt +3 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config.ru.tt +12 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/environments/development.rb.tt +18 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/environments/production.rb.tt +18 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/config/router.rb.tt +6 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/gems/cache/.empty_directory +0 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/mounts/.empty_directory +0 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/public/.empty_directory +0 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/lib/%stack_name%/tmp/.empty_directory +0 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/pancake.init.tt +1 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/spec/%stack_name%_spec.rb.tt +7 -0
- data/lib/pancake/generators/templates/stack/%stack_name%/spec/spec_helper.rb.tt +9 -0
- data/lib/pancake/hooks/inheritable_inner_classes.rb +60 -0
- data/lib/pancake/hooks/on_inherit.rb +34 -0
- data/lib/pancake/master.rb +87 -0
- data/lib/pancake/middleware.rb +354 -0
- data/lib/pancake/mime_types.rb +265 -0
- data/lib/pancake/mixins/publish.rb +125 -0
- data/lib/pancake/mixins/publish/action_options.rb +104 -0
- data/lib/pancake/mixins/render.rb +61 -0
- data/lib/pancake/mixins/request_helper.rb +92 -0
- data/lib/pancake/mixins/stack_helper.rb +44 -0
- data/lib/pancake/mixins/url.rb +10 -0
- data/lib/pancake/more/controller.rb +4 -0
- data/lib/pancake/more/controller/base.rb +34 -0
- data/lib/pancake/paths.rb +218 -0
- data/lib/pancake/router.rb +99 -0
- data/lib/pancake/stack/app.rb +10 -0
- data/lib/pancake/stack/bootloader.rb +79 -0
- data/lib/pancake/stack/configuration.rb +44 -0
- data/lib/pancake/stack/middleware.rb +0 -0
- data/lib/pancake/stack/router.rb +18 -0
- data/lib/pancake/stack/stack.rb +57 -0
- data/lib/pancake/stacks/short.rb +2 -0
- data/lib/pancake/stacks/short/controller.rb +105 -0
- data/lib/pancake/stacks/short/stack.rb +194 -0
- data/spec/helpers/helpers.rb +20 -0
- data/spec/helpers/matchers.rb +25 -0
- data/spec/pancake/bootloaders_spec.rb +109 -0
- data/spec/pancake/configuration_spec.rb +177 -0
- data/spec/pancake/fixtures/foo_stack/pancake.init +0 -0
- data/spec/pancake/fixtures/paths/controllers/controller1.rb +0 -0
- data/spec/pancake/fixtures/paths/controllers/controller2.rb +0 -0
- data/spec/pancake/fixtures/paths/controllers/controller3.rb +0 -0
- data/spec/pancake/fixtures/paths/models/model1.rb +0 -0
- data/spec/pancake/fixtures/paths/models/model2.rb +0 -0
- data/spec/pancake/fixtures/paths/models/model3.rb +0 -0
- data/spec/pancake/fixtures/paths/stack/controllers/controller1.rb +0 -0
- data/spec/pancake/fixtures/paths/stack/models/model3.rb +0 -0
- data/spec/pancake/fixtures/paths/stack/views/view1.erb +0 -0
- data/spec/pancake/fixtures/paths/stack/views/view1.rb +0 -0
- data/spec/pancake/fixtures/paths/stack/views/view2.erb +0 -0
- data/spec/pancake/fixtures/paths/stack/views/view2.haml +0 -0
- data/spec/pancake/fixtures/render_templates/context_template.html.erb +1 -0
- data/spec/pancake/fixtures/render_templates/erb_template.html.erb +1 -0
- data/spec/pancake/fixtures/render_templates/erb_template.json.erb +1 -0
- data/spec/pancake/fixtures/render_templates/haml_template.html.haml +1 -0
- data/spec/pancake/fixtures/render_templates/haml_template.xml.haml +1 -0
- data/spec/pancake/hooks/on_inherit_spec.rb +65 -0
- data/spec/pancake/inheritance_spec.rb +100 -0
- data/spec/pancake/middleware_spec.rb +401 -0
- data/spec/pancake/mime_types_spec.rb +234 -0
- data/spec/pancake/mixins/publish_spec.rb +94 -0
- data/spec/pancake/mixins/render_spec.rb +55 -0
- data/spec/pancake/mixins/stack_helper_spec.rb +46 -0
- data/spec/pancake/pancake_spec.rb +31 -0
- data/spec/pancake/paths_spec.rb +210 -0
- data/spec/pancake/stack/app_spec.rb +28 -0
- data/spec/pancake/stack/bootloader_spec.rb +41 -0
- data/spec/pancake/stack/middleware_spec.rb +0 -0
- data/spec/pancake/stack/router_spec.rb +266 -0
- data/spec/pancake/stack/stack_configuration_spec.rb +101 -0
- data/spec/pancake/stack/stack_spec.rb +55 -0
- data/spec/pancake/stacks/short/controller_spec.rb +287 -0
- data/spec/pancake/stacks/short/router_spec.rb +132 -0
- data/spec/pancake/stacks/short/stack_spec.rb +40 -0
- data/spec/spec_helper.rb +21 -0
- metadata +238 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), "publish", "action_options")
|
|
2
|
+
module Pancake
|
|
3
|
+
module Mixins
|
|
4
|
+
module Publish
|
|
5
|
+
|
|
6
|
+
def self.extended(base)
|
|
7
|
+
base.class_eval do
|
|
8
|
+
class_inheritable_accessor :actions, :formats
|
|
9
|
+
self.actions = {}
|
|
10
|
+
self.formats = [:html]
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Accepts a list of symbols representing the formats each action in the
|
|
15
|
+
# controller will return. By default the list consists only of :html
|
|
16
|
+
#
|
|
17
|
+
# provides :html, :xml
|
|
18
|
+
#
|
|
19
|
+
# @api public
|
|
20
|
+
def provides(*args)
|
|
21
|
+
self.formats = args
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Causes the next method added immediately after it’s call to be defined
|
|
25
|
+
# as an action. It also generates an instance of ActionOptions, which
|
|
26
|
+
# encapsulates all the parameters the action accepts/expects and also
|
|
27
|
+
# the formats that it can potentially return.
|
|
28
|
+
#
|
|
29
|
+
# publish :id => as_integer(:req)
|
|
30
|
+
# def show
|
|
31
|
+
# ...
|
|
32
|
+
# end
|
|
33
|
+
#
|
|
34
|
+
# The example above publishes the action "show" and configures the
|
|
35
|
+
# following options for it:
|
|
36
|
+
#
|
|
37
|
+
# - The parameter 'id' will be coerced into an Integer
|
|
38
|
+
# - It also must not be blank, it is required.
|
|
39
|
+
#
|
|
40
|
+
# The publish declaration can also create much more sophisticated
|
|
41
|
+
# constraints. You can declare a parameter as optional, give it a default
|
|
42
|
+
# value if it is missing.
|
|
43
|
+
#
|
|
44
|
+
# Here, 'start' and 'end' are required — the default — and are coerced into
|
|
45
|
+
# date values. The 'page' parameter is optional, with the default being 1.
|
|
46
|
+
#
|
|
47
|
+
# publish :start => as_date, :end => as_date :page => as_integer(1)
|
|
48
|
+
#
|
|
49
|
+
# For a list of the built in coercions look in the API for methods prefixed
|
|
50
|
+
# with 'as_'. These are intended to be used in your publish declarations.
|
|
51
|
+
#
|
|
52
|
+
# #publish can also handle the specification of formats for an action. It
|
|
53
|
+
# accepts an additional two options, :provides and :only_provides.
|
|
54
|
+
#
|
|
55
|
+
# To the list of globally declared formats, :provides adds additional
|
|
56
|
+
# formats to an action.
|
|
57
|
+
#
|
|
58
|
+
# publish :provides => :xml
|
|
59
|
+
#
|
|
60
|
+
# The :only_provides option overrides any globally declared formats for an
|
|
61
|
+
# action.
|
|
62
|
+
#
|
|
63
|
+
# publish :only_provides => [:json, :xml]
|
|
64
|
+
#
|
|
65
|
+
# @api public
|
|
66
|
+
def publish(opts = {})
|
|
67
|
+
@pending_publication_opts = opts
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Used when declaring configuration for parameters in the publish
|
|
71
|
+
# declaration. It returns an array of the type, default value an
|
|
72
|
+
# additional options.
|
|
73
|
+
#
|
|
74
|
+
# @param type [Object] The
|
|
75
|
+
#
|
|
76
|
+
# The current supported types are
|
|
77
|
+
# - :integer
|
|
78
|
+
# - :date
|
|
79
|
+
# - :string
|
|
80
|
+
#
|
|
81
|
+
# For details on the options supported by each type, please see the
|
|
82
|
+
# corresponding methods declared in the ActionOptions class. These methods
|
|
83
|
+
# are named as the type, prefixed with 'validate_and_coerce_'
|
|
84
|
+
#
|
|
85
|
+
#
|
|
86
|
+
# @example
|
|
87
|
+
# Here is an example where we declare an integer and that it is required
|
|
88
|
+
#
|
|
89
|
+
# as(:integer, :req)
|
|
90
|
+
#
|
|
91
|
+
# Or that it is optional, but has a default value if it is missing.
|
|
92
|
+
#
|
|
93
|
+
# as(:integer, 21)
|
|
94
|
+
#
|
|
95
|
+
# @api public
|
|
96
|
+
def as(type, default = :req, opts = {})
|
|
97
|
+
[type, default, opts]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Takes a parameters hash, and validates each entry against the options
|
|
101
|
+
# defined for this action. It will flag required params when missing,
|
|
102
|
+
# insert defaults or coerce values into the desired type. It mutates
|
|
103
|
+
# the params hash itself.
|
|
104
|
+
#
|
|
105
|
+
# @api private
|
|
106
|
+
def validate_and_coerce_params(action, params)
|
|
107
|
+
actions[action].validate_and_coerce(params)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# This hook is used in conjunction with the #publish method to expose
|
|
112
|
+
# instance methods as actions. Obviously, it should never be called
|
|
113
|
+
# directly :)
|
|
114
|
+
#
|
|
115
|
+
# @api private
|
|
116
|
+
def method_added(name)
|
|
117
|
+
super
|
|
118
|
+
if @pending_publication_opts
|
|
119
|
+
self.actions[name.to_s] = ActionOptions.new(formats, @pending_publication_opts)
|
|
120
|
+
@pending_publication_opts = nil
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end # Publish
|
|
124
|
+
end # Mixins
|
|
125
|
+
end # Pancake
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
module Pancake
|
|
2
|
+
module Mixins
|
|
3
|
+
module Publish
|
|
4
|
+
class ActionOptions
|
|
5
|
+
attr_reader :params, :formats, :default
|
|
6
|
+
CONFIG_OPTIONS = [:provides, :only_provides]
|
|
7
|
+
|
|
8
|
+
# Generates a new instance of the class. This instance encapsulates the
|
|
9
|
+
# options and logic needed to validate the parameters being input into
|
|
10
|
+
# a controller action. First argument is a list of symbols for the
|
|
11
|
+
# formats it supports. The second is hash of options. Typically this
|
|
12
|
+
# hash is generated by the publish declaration in a controller.
|
|
13
|
+
#
|
|
14
|
+
# TODO: Allow params to be grouped together
|
|
15
|
+
#
|
|
16
|
+
# @api private
|
|
17
|
+
def initialize(default_formats, opts)
|
|
18
|
+
# Extract the params — excluding configuration — and turn the keys into
|
|
19
|
+
# strings. Additionally, check to see if someone has passed in a a raw
|
|
20
|
+
# value rather than using one of our as_* methods.
|
|
21
|
+
@params = opts.inject({}) do |memo, opt|
|
|
22
|
+
unless CONFIG_OPTIONS.include? opt[0]
|
|
23
|
+
unless opt[1].is_a?(Array)
|
|
24
|
+
raise "Parameter values must be specified with an as_* method. You passed in a #{opt[1].class.to_s}"
|
|
25
|
+
end
|
|
26
|
+
memo[opt[0].to_s] = opt[1]
|
|
27
|
+
end
|
|
28
|
+
memo
|
|
29
|
+
end
|
|
30
|
+
@formats = extract_format_options(default_formats, opts)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Accepts a hash of parameters and replaces each entry with it’s
|
|
34
|
+
# coerced or default value. If an expected param is missing, it will
|
|
35
|
+
# raise an error.
|
|
36
|
+
#
|
|
37
|
+
# TODO: Flag missing params rather than just raising an error
|
|
38
|
+
# TODO: Allow defaults to be dynamically generated, i.e. method call
|
|
39
|
+
#
|
|
40
|
+
# @api private
|
|
41
|
+
def validate_and_coerce(incoming_params)
|
|
42
|
+
missing = []
|
|
43
|
+
params.each do |name, config|
|
|
44
|
+
type, default, opts = config
|
|
45
|
+
value = incoming_params[name]
|
|
46
|
+
|
|
47
|
+
if !value.nil? && value != ""
|
|
48
|
+
incoming_params[name] = send("validate_and_coerce_#{type}", value, opts)
|
|
49
|
+
else
|
|
50
|
+
if default == :req
|
|
51
|
+
missing << [name, type]
|
|
52
|
+
elsif default != :opt
|
|
53
|
+
incoming_params[name] = default
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
[incoming_params, missing]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
# Accepts a string and turns it into an integer. The opts argument is
|
|
63
|
+
# only there to satisfy the interface. it is not used.
|
|
64
|
+
#
|
|
65
|
+
# @api private
|
|
66
|
+
def validate_and_coerce_integer(value, opts)
|
|
67
|
+
value.to_i
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Accepts a string and turns it into a date. The opts argument is
|
|
71
|
+
# only there to satisfy the interface. it is not used.
|
|
72
|
+
#
|
|
73
|
+
# @api private
|
|
74
|
+
def validate_and_coerce_date(value, opts)
|
|
75
|
+
Date.parse(value)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Turns the incoming value into a string. The opts argument is
|
|
79
|
+
# only there to satisfy the interface. it is not used.
|
|
80
|
+
#
|
|
81
|
+
# @api private
|
|
82
|
+
def validate_and_coerce_string(value, opts)
|
|
83
|
+
value.to_s
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Extracts the format options from a hash. It is used to compile the
|
|
87
|
+
# list of formats that an action can provide. It accepts an array of
|
|
88
|
+
# symbols representing the base formats and will add to or overwrite
|
|
89
|
+
# them based on the options in the hash.
|
|
90
|
+
#
|
|
91
|
+
# @api private
|
|
92
|
+
def extract_format_options(defaults, opts)
|
|
93
|
+
@formats = if opts[:provides]
|
|
94
|
+
defaults + [opts[:provides]].flatten
|
|
95
|
+
elsif opts[:only_provides]
|
|
96
|
+
[opts[:only_provides]].flatten
|
|
97
|
+
else
|
|
98
|
+
defaults
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end # ActionOptions
|
|
102
|
+
end # Publish
|
|
103
|
+
end # Mixins
|
|
104
|
+
end # Pancake
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Pancake
|
|
2
|
+
module Mixins
|
|
3
|
+
module Render
|
|
4
|
+
class TemplateNotFound < Pancake::Errors::NotFound; end
|
|
5
|
+
|
|
6
|
+
def self.included(base)
|
|
7
|
+
base.class_eval do
|
|
8
|
+
extend Pancake::Mixins::Render::ClassMethods
|
|
9
|
+
include Pancake::Mixins::Render::InstanceMethods
|
|
10
|
+
|
|
11
|
+
unless ancestors.include?(Pancake::Paths)
|
|
12
|
+
extend Pancake::Paths
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
module ClassMethods
|
|
18
|
+
|
|
19
|
+
def _view_cache
|
|
20
|
+
@_view_cache ||= {}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def _find_template(name)
|
|
24
|
+
renderer = _view_cache[name]
|
|
25
|
+
return renderer if renderer
|
|
26
|
+
|
|
27
|
+
renderer_path = unique_paths_for(:views, :invert => true).detect do |path|
|
|
28
|
+
path.last =~ %r[(#{name})\.\w+$]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
raise TemplateNotFound unless renderer_path
|
|
32
|
+
_view_cache[name] = Tilt.new(renderer_path.join)
|
|
33
|
+
end
|
|
34
|
+
end # ClassMethods
|
|
35
|
+
|
|
36
|
+
module InstanceMethods
|
|
37
|
+
def render(*args)
|
|
38
|
+
opts = Hash === args.last ? args.pop : {}
|
|
39
|
+
name = args.shift
|
|
40
|
+
|
|
41
|
+
return opts[:text] if opts[:text]
|
|
42
|
+
|
|
43
|
+
# Get the template name to use
|
|
44
|
+
template = _template_name_for(name, opts)
|
|
45
|
+
|
|
46
|
+
# get the render template for that name
|
|
47
|
+
renderer = self.class._find_template(template)
|
|
48
|
+
|
|
49
|
+
# Render the results
|
|
50
|
+
renderer.render(self, opts)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
def _template_name_for(name, opts)
|
|
55
|
+
opts[:format] ||= params[:format] || :html
|
|
56
|
+
"#{name}.#{opts[:format]}"
|
|
57
|
+
end
|
|
58
|
+
end # InstanceMethods
|
|
59
|
+
end # Render
|
|
60
|
+
end # Mixins
|
|
61
|
+
end # Pancake
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module Pancake
|
|
2
|
+
module Mixins
|
|
3
|
+
# Some helpers for requests that come in handy for applications that
|
|
4
|
+
# are part of stacks
|
|
5
|
+
module RequestHelper
|
|
6
|
+
|
|
7
|
+
# A setter for the rack environment
|
|
8
|
+
# @api public
|
|
9
|
+
def env=(env)
|
|
10
|
+
@env = env
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# An accessor for the rack environment variable
|
|
14
|
+
# @api public
|
|
15
|
+
def env
|
|
16
|
+
@env
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def headers
|
|
20
|
+
@headers ||= {}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def status
|
|
24
|
+
@status ||= 200
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def status=(st)
|
|
28
|
+
@status = st
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Generate a url for the current stacks router.
|
|
32
|
+
#
|
|
33
|
+
# @example
|
|
34
|
+
# class MyApp
|
|
35
|
+
# router do |r|
|
|
36
|
+
# r.add("/foo").name(:foo)
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
# include Pancake::RequestHelper
|
|
40
|
+
# # snip
|
|
41
|
+
# def call(env)
|
|
42
|
+
# @env = env
|
|
43
|
+
# url(:foo) # => "/foo"
|
|
44
|
+
# end
|
|
45
|
+
# end
|
|
46
|
+
#
|
|
47
|
+
# @see Usher
|
|
48
|
+
# @see Pancake::Router
|
|
49
|
+
# @api public
|
|
50
|
+
# @author Daniel Neighman
|
|
51
|
+
def url(name, opts = {})
|
|
52
|
+
konfig = request.env[Pancake::Router::CONFIGURATION_KEY]
|
|
53
|
+
konfig.router.generate(name, opts)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Generate a url for any registered configuration with a router
|
|
57
|
+
#
|
|
58
|
+
# @example
|
|
59
|
+
# # an application declared with MyApp.stackup(:app_name =>
|
|
60
|
+
#:some_app)
|
|
61
|
+
# url_for(:some_app, :my_named_route)
|
|
62
|
+
#
|
|
63
|
+
# # An application with no name specified
|
|
64
|
+
# url_for(MyApp, :my_named_route)
|
|
65
|
+
#
|
|
66
|
+
# @see Usher
|
|
67
|
+
# @see Pancake::Router
|
|
68
|
+
# @api public
|
|
69
|
+
# @author Daniel Neighman
|
|
70
|
+
def url_for(app_name, name_or_opts, opts = {})
|
|
71
|
+
if konfig = Pancake.configuration.configs[app_name]
|
|
72
|
+
konfig.router.generate(name_or_opts, opts)
|
|
73
|
+
else
|
|
74
|
+
raise Pancake::Errors::UnknownConfiguration
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# A handy request method that gets hold of the current request
|
|
79
|
+
# object for the current rack request.
|
|
80
|
+
# Any including class _must_ provide an +env+ method that exposes
|
|
81
|
+
# the rack request environment
|
|
82
|
+
#
|
|
83
|
+
# @see Rack::Request
|
|
84
|
+
# @api public
|
|
85
|
+
# @author Daniel Neighman
|
|
86
|
+
def request
|
|
87
|
+
@request ||= Rack::Request.new(env)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end # RequestHelper
|
|
91
|
+
end # Mixins
|
|
92
|
+
end # Pancake
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Pancake
|
|
2
|
+
module Mixins
|
|
3
|
+
module StackHelper
|
|
4
|
+
def self.included(base)
|
|
5
|
+
base.class_inheritable_accessor :_stack_class
|
|
6
|
+
base.extend ClassMethods
|
|
7
|
+
base.class_eval do
|
|
8
|
+
include ::Pancake::Mixins::StackHelper::InstanceMethods
|
|
9
|
+
end
|
|
10
|
+
base.stack_class
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module ClassMethods
|
|
14
|
+
def stack_class
|
|
15
|
+
return @_stack_class if @_stack_class
|
|
16
|
+
klass = nil
|
|
17
|
+
ns = name.split("::")
|
|
18
|
+
until ns.empty? || klass
|
|
19
|
+
r = Object.full_const_get(ns.join("::"))
|
|
20
|
+
if r.ancestors.include?(::Pancake::Stack)
|
|
21
|
+
klass = r
|
|
22
|
+
else
|
|
23
|
+
ns.pop
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
if klass.nil?
|
|
27
|
+
raise "#{name} is not from a stack" unless _stack_class
|
|
28
|
+
else
|
|
29
|
+
self._stack_class = r
|
|
30
|
+
end
|
|
31
|
+
_stack_class
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
module InstanceMethods
|
|
37
|
+
def stack_class
|
|
38
|
+
self.class.stack_class
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end # StackHelper
|
|
43
|
+
end # Mixins
|
|
44
|
+
end # Pancake
|