orange 0.0.3 → 0.0.4
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/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
|