orange 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/orange/application.rb +1 -1
- data/lib/orange/carton.rb +55 -27
- data/lib/orange/cartons/site_carton.rb +4 -1
- data/lib/orange/core.rb +10 -2
- data/lib/orange/magick.rb +11 -0
- data/lib/orange/middleware/access_control.rb +16 -7
- data/lib/orange/middleware/base.rb +40 -1
- data/lib/orange/middleware/flex_router.rb +59 -0
- data/lib/orange/middleware/route_context.rb +2 -2
- data/lib/orange/middleware/route_site.rb +1 -1
- data/lib/orange/middleware/show_exceptions.rb +3 -1
- data/lib/orange/middleware/site_load.rb +14 -1
- data/lib/orange/middleware/static.rb +0 -2
- data/lib/orange/middleware/template.rb +3 -1
- data/lib/orange/resources/admin_resource.rb +25 -0
- data/lib/orange/resources/mapper.rb +3 -0
- data/lib/orange/resources/model_resource.rb +15 -9
- data/lib/orange/resources/page_parts.rb +0 -7
- data/lib/orange/resources/parser.rb +5 -4
- data/lib/orange/resources/singleton_model_resource.rb +7 -0
- data/lib/orange/resources/sitemap_resource.rb +96 -0
- data/lib/orange/stack.rb +5 -5
- data/spec/{application_spec.rb → orange/application_spec.rb} +0 -0
- data/spec/orange/carton_spec.rb +136 -0
- data/spec/{core_spec.rb → orange/core_spec.rb} +10 -0
- data/spec/{magick_spec.rb → orange/magick_spec.rb} +11 -0
- data/spec/orange/middleware/access_control_spec.rb +3 -0
- data/spec/orange/middleware/base_spec.rb +37 -0
- data/spec/orange/middleware/database_spec.rb +3 -0
- data/spec/orange/middleware/globals_spec.rb +3 -0
- data/spec/orange/middleware/recapture_spec.rb +3 -0
- data/spec/orange/middleware/rerouter_spec.rb +3 -0
- data/spec/orange/middleware/restful_router_spec.rb +3 -0
- data/spec/orange/middleware/route_context_spec.rb +3 -0
- data/spec/orange/middleware/route_site_spec.rb +3 -0
- data/spec/orange/middleware/show_exceptions_spec.rb +3 -0
- data/spec/orange/middleware/site_load_spec.rb +26 -0
- data/spec/orange/middleware/static_file_spec.rb +3 -0
- data/spec/orange/middleware/static_spec.rb +3 -0
- data/spec/orange/middleware/template_spec.rb +3 -0
- data/spec/{mock → orange/mock}/mock_app.rb +0 -0
- data/spec/orange/mock/mock_carton.rb +43 -0
- data/spec/{mock → orange/mock}/mock_core.rb +0 -0
- data/spec/{mock → orange/mock}/mock_middleware.rb +8 -0
- data/spec/{mock → orange/mock}/mock_mixins.rb +0 -0
- data/spec/{mock → orange/mock}/mock_model_resource.rb +4 -0
- data/spec/{mock → orange/mock}/mock_pulp.rb +0 -0
- data/spec/{mock → orange/mock}/mock_resource.rb +0 -0
- data/spec/{mock → orange/mock}/mock_router.rb +0 -0
- data/spec/{orange_spec.rb → orange/orange_spec.rb} +0 -0
- data/spec/{packet_spec.rb → orange/packet_spec.rb} +0 -0
- data/spec/{resource_spec.rb → orange/resource_spec.rb} +0 -0
- data/spec/orange/resources/admin_resource_spec.rb +16 -0
- data/spec/{resources → orange/resources}/mapper_spec.rb +0 -0
- data/spec/{resources → orange/resources}/model_resource_spec.rb +104 -0
- data/spec/{resources → orange/resources}/parser_spec.rb +0 -0
- data/spec/{resources → orange/resources}/routable_resource_spec.rb +0 -0
- data/spec/orange/resources/singleton_model_resource_spec.rb +4 -0
- data/spec/{resources/flex_router_spec.rb → orange/resources/sitemap_resource_spec.rb} +1 -1
- data/spec/orange/spec_helper.rb +51 -0
- data/spec/{stack_spec.rb → orange/stack_spec.rb} +0 -0
- metadata +45 -40
- data/lib/orange/resources/flex_router.rb +0 -13
- data/spec/carton_spec.rb +0 -5
- data/spec/middleware/access_control_spec.rb +0 -0
- data/spec/middleware/base_spec.rb +0 -0
- data/spec/middleware/database_spec.rb +0 -0
- data/spec/middleware/globals_spec.rb +0 -0
- data/spec/middleware/recapture_spec.rb +0 -0
- data/spec/middleware/rerouter_spec.rb +0 -0
- data/spec/middleware/restful_router_spec.rb +0 -0
- data/spec/middleware/route_context_spec.rb +0 -0
- data/spec/middleware/route_site_spec.rb +0 -0
- data/spec/middleware/show_exceptions_spec.rb +0 -0
- data/spec/middleware/site_load_spec.rb +0 -0
- data/spec/middleware/static_file_spec.rb +0 -0
- data/spec/middleware/static_spec.rb +0 -0
- data/spec/middleware/template_spec.rb +0 -0
- data/spec/mock/mock_carton.rb +0 -15
- data/spec/spec_helper.rb +0 -20
data/lib/orange/application.rb
CHANGED
@@ -81,7 +81,7 @@ module Orange
|
|
81
81
|
# The intent is for the application subclass to override this method
|
82
82
|
# and use it to handle packets not routed by Stack middleware.
|
83
83
|
def route(packet)
|
84
|
-
raise
|
84
|
+
raise "default response from Orange::Application.route"
|
85
85
|
end
|
86
86
|
|
87
87
|
# Used to set optional values at class level. Will be merged into the options
|
data/lib/orange/carton.rb
CHANGED
@@ -7,7 +7,9 @@ module Orange
|
|
7
7
|
#
|
8
8
|
# All subclasses should start by declaring the "id" attribute. All models
|
9
9
|
# are assumed to have an id attribute by most everything else, so it's
|
10
|
-
# a good idea to have one.
|
10
|
+
# a good idea to have one. Also, we use this to tie in initialization before
|
11
|
+
# using the other dsl-ish methods (since these other methods are class level
|
12
|
+
# and would happen before initialize ever gets called)
|
11
13
|
#
|
12
14
|
# Orange::Carton adds many shortcut methods for adding various datatypes
|
13
15
|
# to the model in a more declarative style (`id` vs `property :id, Serial`)
|
@@ -15,8 +17,14 @@ module Orange
|
|
15
17
|
# For classes that don't need anything but scaffolding, there's the
|
16
18
|
# as_resource method, which automatically creates a scaffolding resource
|
17
19
|
# for the model.
|
20
|
+
#
|
21
|
+
# A model that doesn't need scaffolded at all could optionally forgo the carton
|
22
|
+
# class and just include DataMapper::Resource. All carton methods are to
|
23
|
+
# improve scaffolding capability.
|
18
24
|
class Carton
|
19
|
-
|
25
|
+
SCAFFOLD_OPTIONS = [:display_name] unless defined?(SCAFFOLD_OPTIONS)
|
26
|
+
# Declares a ModelResource subclass that scaffolds this carton
|
27
|
+
# The Subclass will have the name of the carton followed by "_Resource"
|
20
28
|
def self.as_resource
|
21
29
|
name = self.to_s
|
22
30
|
eval <<-HEREDOC
|
@@ -26,22 +34,28 @@ module Orange
|
|
26
34
|
HEREDOC
|
27
35
|
end
|
28
36
|
|
29
|
-
#
|
37
|
+
# Include DataMapper types (required to be able to use Serial)
|
30
38
|
include DataMapper::Types
|
31
39
|
|
40
|
+
# Do setup of object and declare an id
|
32
41
|
def self.id
|
33
42
|
include DataMapper::Resource
|
34
|
-
|
43
|
+
property(:id, Serial)
|
35
44
|
@scaffold_properties = []
|
36
45
|
init
|
37
46
|
end
|
38
47
|
|
48
|
+
def self.scaffold_properties
|
49
|
+
@scaffold_properties ||= []
|
50
|
+
end
|
51
|
+
|
52
|
+
# Stub init method
|
39
53
|
def self.init
|
40
54
|
end
|
41
55
|
|
42
56
|
# Return properties that should be shown for a given context
|
43
|
-
def self.form_props(context)
|
44
|
-
|
57
|
+
def self.form_props(context = :live)
|
58
|
+
scaffold_properties.select{|p| p[:levels].include?(context) }
|
45
59
|
end
|
46
60
|
|
47
61
|
# Helper to wrap properties into admin level
|
@@ -65,25 +79,40 @@ module Orange
|
|
65
79
|
@levels = false
|
66
80
|
end
|
67
81
|
|
82
|
+
def self.add_scaffold(name, type, dm_type, opts)
|
83
|
+
scaffold_properties << {:name => name, :type => type, :levels => @levels}.merge(opts) if @levels
|
84
|
+
opts = opts.delete_if{|k,v| SCAFFOLD_OPTIONS.include?(k)} # DataMapper doesn't like arbitrary opts
|
85
|
+
self.property(name, dm_type, opts)
|
86
|
+
end
|
87
|
+
|
68
88
|
# Define a helper for title type database stuff
|
69
89
|
# Show in a context if wrapped in one of the helpers
|
70
90
|
def self.title(name, opts = {})
|
71
|
-
|
72
|
-
self.property(name, String, opts)
|
91
|
+
add_scaffold(name, :title, String, opts)
|
73
92
|
end
|
74
93
|
|
75
94
|
# Define a helper for fulltext type database stuff
|
76
95
|
# Show in a context if wrapped in one of the helpers
|
77
96
|
def self.fulltext(name, opts = {})
|
78
|
-
|
79
|
-
|
97
|
+
add_scaffold(name, :fulltext, Text, opts)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Define a helper for boolean type database stuff
|
101
|
+
# Show in a context if wrapped in one of the helpers
|
102
|
+
def self.boolean(name, opts = {})
|
103
|
+
add_scaffold(name, :boolean, Boolean, opts)
|
80
104
|
end
|
81
105
|
|
82
106
|
# Define a helper for input type="text" type database stuff
|
83
107
|
# Show in a context if wrapped in one of the helpers
|
84
108
|
def self.text(name, opts = {})
|
85
|
-
|
86
|
-
|
109
|
+
add_scaffold(name, :text, String, opts)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Define a helper for type database stuff
|
113
|
+
# Show in a context if wrapped in one of the helpers
|
114
|
+
def self.expose(name, opts = {})
|
115
|
+
scaffold_properties << {:name => name, :type => :text, :levels => @levels, :opts => opts} if @levels
|
87
116
|
end
|
88
117
|
|
89
118
|
# Define a helper for input type="text" type database stuff
|
@@ -93,35 +122,34 @@ module Orange
|
|
93
122
|
end
|
94
123
|
|
95
124
|
# Override DataMapper to include context sensitivity (as set by helpers)
|
96
|
-
def self.
|
125
|
+
def self.scaffold_property(name, type, opts = {})
|
97
126
|
my_type = type.to_s.downcase.to_sym
|
98
|
-
|
99
|
-
property(name, type, opts)
|
127
|
+
add_scaffold(name, my_type, type, opts)
|
100
128
|
end
|
101
129
|
|
102
130
|
|
103
|
-
# For more generic cases, use same syntax as DataMapper
|
104
|
-
#
|
131
|
+
# For more generic cases, use same syntax as DataMapper does.
|
132
|
+
# The difference is that this will make it an admin property.
|
105
133
|
def self.admin_property(name, type, opts = {})
|
106
134
|
my_type = type.to_s.downcase.to_sym
|
107
|
-
|
108
|
-
|
135
|
+
opts[:levels] = [:admin, :orange]
|
136
|
+
add_scaffold(name, my_type, type, opts)
|
109
137
|
end
|
110
138
|
|
111
|
-
# For more generic cases, use same syntax as DataMapper
|
112
|
-
#
|
139
|
+
# For more generic cases, use same syntax as DataMapper does.
|
140
|
+
# The difference is that this will make it a front property.
|
113
141
|
def self.front_property(name, type, opts = {})
|
114
142
|
my_type = type.to_s.downcase.to_sym
|
115
|
-
|
116
|
-
|
143
|
+
opts[:levels] = [:live, :admin, :orange]
|
144
|
+
add_scaffold(name, my_type, type, opts)
|
117
145
|
end
|
118
146
|
|
119
|
-
# For more generic cases, use same syntax as DataMapper
|
120
|
-
#
|
147
|
+
# For more generic cases, use same syntax as DataMapper does.
|
148
|
+
# The difference is that this will make it an orange property.
|
121
149
|
def self.orange_property(name, type, opts = {})
|
122
150
|
my_type = type.to_s.downcase.to_sym
|
123
|
-
|
124
|
-
|
151
|
+
opts[:levels] = [:orange]
|
152
|
+
add_scaffold(name, my_type, type, opts)
|
125
153
|
end
|
126
154
|
|
127
155
|
end
|
@@ -1,6 +1,9 @@
|
|
1
|
-
require '
|
1
|
+
require 'orange/carton'
|
2
2
|
|
3
3
|
module Orange
|
4
|
+
# Defines a carton that belongs to a specific site.
|
5
|
+
# (Subclasses should be sure to call super if they override init, since
|
6
|
+
# it is what defines the relationship)
|
4
7
|
class SiteCarton < Carton
|
5
8
|
def self.init
|
6
9
|
belongs_to :orange_site, 'Orange::Site'
|
data/lib/orange/core.rb
CHANGED
@@ -57,6 +57,7 @@ module Orange
|
|
57
57
|
load(Orange::Parser.new, :parser)
|
58
58
|
load(Orange::Mapper.new, :mapper)
|
59
59
|
load(Orange::PageParts.new, :page_parts)
|
60
|
+
load(Orange::AdminResource.new, :admin)
|
60
61
|
afterLoad
|
61
62
|
self
|
62
63
|
end
|
@@ -165,9 +166,16 @@ module Orange
|
|
165
166
|
# Accesses resources array, stored as a hash {:short_name => Resource instance,...}
|
166
167
|
#
|
167
168
|
# @param [Symbol] name the short name for the requested resource
|
169
|
+
# @param [optional, Boolean] ignore Whether to ignore any calls to resource if not found
|
170
|
+
# (false is default). This will allow method calls to non-existent resources. Should be
|
171
|
+
# used with caution.
|
168
172
|
# @return [Orange::Resource] the resource for the given short name
|
169
|
-
def [](name)
|
170
|
-
|
173
|
+
def [](name, ignore = false)
|
174
|
+
if ignore && !loaded?(name)
|
175
|
+
Ignore.new
|
176
|
+
else
|
177
|
+
@resources[name]
|
178
|
+
end
|
171
179
|
end
|
172
180
|
|
173
181
|
# Includes module in the Packet class
|
data/lib/orange/magick.rb
CHANGED
@@ -64,6 +64,17 @@ module Orange
|
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
|
+
# This class acts as a simple sink for ignoring messages, it will return itself
|
68
|
+
# for any message call. Orange::Core can optionally return this when trying
|
69
|
+
# to access resources so that you can make method calls to a resource that
|
70
|
+
# might not be really there. It will silently swallow any errors that might arrise,
|
71
|
+
# so this should be used with caution.
|
72
|
+
class Ignore
|
73
|
+
def method_missing(name, *args, &block)
|
74
|
+
return self
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
67
78
|
# Simple class for evaluating options and allowing us to access them.
|
68
79
|
class Options
|
69
80
|
|
@@ -3,13 +3,23 @@ require 'orange/middleware/base'
|
|
3
3
|
|
4
4
|
|
5
5
|
module Orange::Middleware
|
6
|
-
|
6
|
+
# This middleware locks down entire contexts and puts them behind an openid
|
7
|
+
# login system. Currently only supports a single user id.
|
8
|
+
#
|
9
|
+
#
|
7
10
|
class AccessControl < Base
|
8
|
-
|
11
|
+
# Sets up the options for the middleware
|
12
|
+
# @param [Hash] opts hash of options
|
13
|
+
# @option opts [Boolean] :openid Whether to use openid logins or not (currently only option)
|
14
|
+
# @option opts [Boolean] :handle_login Whether the access control system should handle
|
15
|
+
# presenting the login form, or let other parts of the app do that.
|
16
|
+
# @option opts [Boolean] :config_id Whether to use the id set in a config file
|
17
|
+
|
18
|
+
def init(opts = {})
|
9
19
|
defs = {:locked => [:admin, :orange], :login => '/login',
|
10
20
|
:handle_login => true, :openid => true, :config_id => true}
|
11
|
-
opts =
|
12
|
-
@openid = opts
|
21
|
+
opts = opts.with_defaults!(defs)
|
22
|
+
@openid = opts[:openid]
|
13
23
|
@locked = opts[:locked]
|
14
24
|
@login = opts[:login]
|
15
25
|
@handle = opts[:handle_login]
|
@@ -65,15 +75,14 @@ module Orange::Middleware
|
|
65
75
|
packet['user.openid.response'] = resp
|
66
76
|
|
67
77
|
after = packet.session.has_key?('user.after_login') ?
|
68
|
-
packet.session['user.after_login'] :
|
78
|
+
packet.session['user.after_login'] : '/'
|
69
79
|
packet.session['user.after_login'] = false
|
70
80
|
|
71
81
|
# Save id into session if we have one.
|
72
82
|
packet.session['user.id'] = packet['user.id']
|
73
83
|
|
74
84
|
# If the user was supposed to be going somewhere, redirect there
|
75
|
-
packet.reroute(after)
|
76
|
-
packet.reroute('/')
|
85
|
+
packet.reroute(after)
|
77
86
|
false
|
78
87
|
else
|
79
88
|
packet.session['flash.error'] = resp.status
|
@@ -10,30 +10,69 @@ require 'orange/packet'
|
|
10
10
|
# a basic call
|
11
11
|
module Orange::Middleware
|
12
12
|
class Base
|
13
|
+
# Initialize will set the core and downstream app, then call init
|
14
|
+
# subclasses should override init instead of initialize
|
15
|
+
# @param [Object] app a downstream app
|
16
|
+
# @param [Orange::Core] core the orange core
|
17
|
+
# @param [optional, Array] args any arguments
|
13
18
|
def initialize(app, core, *args)
|
14
19
|
@app = app
|
15
20
|
@core = core
|
16
21
|
init(*args)
|
17
22
|
end
|
18
23
|
|
24
|
+
# A stub method that subclasses can override to handle initialization
|
25
|
+
# @return [void]
|
19
26
|
def init(*args)
|
20
27
|
end
|
21
28
|
|
29
|
+
# The standard Rack "call". By default, Orange Middleware wraps the env into
|
30
|
+
# an Orange::Packet and passes it on to #packet_call. Subclasses will typically
|
31
|
+
# override packet_call rather than overriding call directly.
|
32
|
+
#
|
33
|
+
# Orange Middleware
|
34
|
+
# should expect to have this method ignored by upstream Orange-aware apps in
|
35
|
+
# favor of calling packet_call directly.
|
36
|
+
# @param [Hash] env the hash of environment variables given by the rack interface.
|
37
|
+
# @return [Array] the standard Rack striplet of status, headers and content
|
22
38
|
def call(env)
|
23
39
|
packet = Orange::Packet.new(@core, env)
|
24
40
|
packet_call(packet)
|
25
41
|
end
|
26
42
|
|
43
|
+
# Like the standard call, but with the env hash already wrapped into a Packet
|
44
|
+
# This is called automatically as part of #call, so subclasses can have a packet
|
45
|
+
# without having to initialize it. It will be called directly by Orange-aware
|
46
|
+
# upstream middleware, skipping the step of initializing the packet during #call.
|
47
|
+
#
|
48
|
+
# Passing the packet downstream should be done with #pass rather than the Rack
|
49
|
+
# standard @app.call, since #pass will take the packet and do a #packet_call
|
50
|
+
# if possible.
|
51
|
+
# @param [Orange::Packet] packet the packet corresponding to this env
|
52
|
+
# @return [Array] the standard Rack striplet of status, headers and content
|
27
53
|
def packet_call(packet)
|
28
54
|
pass packet
|
29
55
|
end
|
30
56
|
|
57
|
+
# Pass will sent the packet to the downstream app by calling call or packet call.
|
58
|
+
# Calling pass on a packet is the preferred way to call downstream apps, as it
|
59
|
+
# will call packet_call directly if possible (to avoid reinitializing the packet)
|
60
|
+
# @param [Orange::Packet] packet the packet to pass to downstream apps
|
61
|
+
# @return [Array] the standard Rack striplet of status, headers and content
|
31
62
|
def pass(packet)
|
32
|
-
@app.
|
63
|
+
if @app.respond_to?(:packet_call)
|
64
|
+
@app.packet_call(packet)
|
65
|
+
else
|
66
|
+
@app.call(packet.env)
|
67
|
+
end
|
33
68
|
end
|
34
69
|
|
70
|
+
# Accessor for @core, which is the stack's instance of Orange::Core
|
71
|
+
# @return [Orange::Core] the stack's instance of Orange::Core
|
35
72
|
def orange; @core; end
|
36
73
|
|
74
|
+
# Help stack traces
|
75
|
+
# @return [String] string representing this middleware (#to_s)
|
37
76
|
def inspect
|
38
77
|
self.to_s
|
39
78
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'orange/middleware/base'
|
2
|
+
|
3
|
+
module Orange::Middleware
|
4
|
+
class FlexRouter < Base
|
5
|
+
def init(*args)
|
6
|
+
opts = args.extract_options!.with_defaults(:contexts => [:admin, :orange], :root_resource => :not_found)
|
7
|
+
@contexts = opts[:contexts]
|
8
|
+
@root_resource = opts[:root_resource]
|
9
|
+
end
|
10
|
+
|
11
|
+
# sets resource, resource_id, resource_action and resource_path
|
12
|
+
# /resource/id/action/[resource/path/if/any]
|
13
|
+
# /resource/action/[resource/path/if/any]
|
14
|
+
#
|
15
|
+
# In future - support for nested resources
|
16
|
+
def packet_call(packet)
|
17
|
+
return (pass packet) if packet['route.router'] # Don't route if other middleware
|
18
|
+
# already has
|
19
|
+
if(@contexts.include?(packet['route.context']))
|
20
|
+
path = packet['route.path'] || packet.request.path_info
|
21
|
+
parts = path.split('/')
|
22
|
+
pad = parts.shift
|
23
|
+
if !parts.empty?
|
24
|
+
resource = parts.shift
|
25
|
+
if orange.loaded?(resource.to_sym)
|
26
|
+
packet['route.resource'] = resource.to_sym
|
27
|
+
if !parts.empty?
|
28
|
+
second = parts.shift
|
29
|
+
if second =~ /^\d+$/
|
30
|
+
packet['route.resource_id'] = second
|
31
|
+
if !parts.empty?
|
32
|
+
packet['route.resource_action'] = parts.shift.to_sym
|
33
|
+
end
|
34
|
+
else
|
35
|
+
packet['route.resource_action'] = second.to_sym
|
36
|
+
end
|
37
|
+
end # end check for second part
|
38
|
+
else
|
39
|
+
parts.unshift(resource)
|
40
|
+
end # end check for loaded resource
|
41
|
+
end # end check for nonempty route
|
42
|
+
|
43
|
+
packet['route.resource'] ||= @root_resource
|
44
|
+
packet['route.resource_path'] = parts.unshift(pad).join('/')
|
45
|
+
packet['route.router'] = self
|
46
|
+
end # End context match if
|
47
|
+
|
48
|
+
pass packet
|
49
|
+
end
|
50
|
+
|
51
|
+
def route(packet)
|
52
|
+
resource = packet['route.resource']
|
53
|
+
raise 'resource not found' unless orange.loaded? resource
|
54
|
+
mode = packet['route.resource_action'] ||
|
55
|
+
(packet['route.resource_id'] ? :show : :list)
|
56
|
+
packet[:content] = orange[resource].view packet
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'orange/middleware/base'
|
2
2
|
|
3
3
|
module Orange::Middleware
|
4
|
-
# This middleware handles setting orange.env[
|
4
|
+
# This middleware handles setting orange.env['route.context']
|
5
5
|
# to a value based on the route, if any. The route is then
|
6
6
|
# trimmed before continuing on.
|
7
7
|
class RouteContext < Base
|
@@ -33,7 +33,7 @@ module Orange::Middleware
|
|
33
33
|
packet['route.context'] = @default
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
pass packet
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -11,7 +11,9 @@ module Orange::Middleware
|
|
11
11
|
#
|
12
12
|
# Be careful when you use this on public-facing sites as it could
|
13
13
|
# reveal information helpful to attackers.
|
14
|
-
|
14
|
+
#
|
15
|
+
# Orange::Middleware::ShowExceptions is a slightly modified
|
16
|
+
# version of Rack::ShowExceptions
|
15
17
|
class ShowExceptions < Base
|
16
18
|
CONTEXT = 7
|
17
19
|
|
@@ -11,7 +11,16 @@ module Orange::Middleware
|
|
11
11
|
def packet_call(packet)
|
12
12
|
url = packet['route.site_url']
|
13
13
|
site = Orange::Site.first(:url.like => url)
|
14
|
-
|
14
|
+
if site
|
15
|
+
packet['site'] = site
|
16
|
+
elsif
|
17
|
+
nil
|
18
|
+
else
|
19
|
+
s = Orange::Site.new({:url => packet['route.site_url'],
|
20
|
+
:name => 'An Orange Site'})
|
21
|
+
s.save
|
22
|
+
packet['site'] = s
|
23
|
+
end
|
15
24
|
pass packet
|
16
25
|
end
|
17
26
|
end
|
@@ -29,5 +38,9 @@ module Orange
|
|
29
38
|
|
30
39
|
class SiteResource < ModelResource
|
31
40
|
use Orange::Site
|
41
|
+
def afterLoad
|
42
|
+
orange[:admin, true].add_link('Settings', :resource => @my_orange_name,
|
43
|
+
:text => 'Site')
|
44
|
+
end
|
32
45
|
end
|
33
46
|
end
|