orange-core 0.5.3
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/README.markdown +145 -0
- data/lib/orange-core.rb +8 -0
- data/lib/orange-core/application.rb +132 -0
- data/lib/orange-core/assets/css/exceptions.css +50 -0
- data/lib/orange-core/assets/js/exceptions.js +44 -0
- data/lib/orange-core/carton.rb +178 -0
- data/lib/orange-core/core.rb +266 -0
- data/lib/orange-core/magick.rb +270 -0
- data/lib/orange-core/middleware/base.rb +96 -0
- data/lib/orange-core/middleware/database.rb +45 -0
- data/lib/orange-core/middleware/four_oh_four.rb +45 -0
- data/lib/orange-core/middleware/globals.rb +17 -0
- data/lib/orange-core/middleware/loader.rb +13 -0
- data/lib/orange-core/middleware/rerouter.rb +53 -0
- data/lib/orange-core/middleware/restful_router.rb +99 -0
- data/lib/orange-core/middleware/route_context.rb +39 -0
- data/lib/orange-core/middleware/route_site.rb +51 -0
- data/lib/orange-core/middleware/show_exceptions.rb +80 -0
- data/lib/orange-core/middleware/static.rb +67 -0
- data/lib/orange-core/middleware/static_file.rb +32 -0
- data/lib/orange-core/middleware/template.rb +60 -0
- data/lib/orange-core/packet.rb +232 -0
- data/lib/orange-core/plugin.rb +172 -0
- data/lib/orange-core/resource.rb +96 -0
- data/lib/orange-core/resources/mapper.rb +36 -0
- data/lib/orange-core/resources/model_resource.rb +228 -0
- data/lib/orange-core/resources/not_found.rb +10 -0
- data/lib/orange-core/resources/page_parts.rb +68 -0
- data/lib/orange-core/resources/parser.rb +113 -0
- data/lib/orange-core/resources/routable_resource.rb +16 -0
- data/lib/orange-core/resources/scaffold.rb +106 -0
- data/lib/orange-core/stack.rb +226 -0
- data/lib/orange-core/templates/exceptions.haml +111 -0
- data/lib/orange-core/views/default_resource/create.haml +4 -0
- data/lib/orange-core/views/default_resource/edit.haml +9 -0
- data/lib/orange-core/views/default_resource/list.haml +10 -0
- data/lib/orange-core/views/default_resource/show.haml +4 -0
- data/lib/orange-core/views/default_resource/table_row.haml +7 -0
- data/lib/orange-core/views/not_found/404.haml +2 -0
- data/spec/orange-core/application_spec.rb +183 -0
- data/spec/orange-core/carton_spec.rb +136 -0
- data/spec/orange-core/core_spec.rb +248 -0
- data/spec/orange-core/magick_spec.rb +96 -0
- data/spec/orange-core/middleware/base_spec.rb +38 -0
- data/spec/orange-core/middleware/globals_spec.rb +3 -0
- data/spec/orange-core/middleware/rerouter_spec.rb +3 -0
- data/spec/orange-core/middleware/restful_router_spec.rb +3 -0
- data/spec/orange-core/middleware/route_context_spec.rb +3 -0
- data/spec/orange-core/middleware/route_site_spec.rb +3 -0
- data/spec/orange-core/middleware/show_exceptions_spec.rb +3 -0
- data/spec/orange-core/middleware/static_file_spec.rb +3 -0
- data/spec/orange-core/middleware/static_spec.rb +3 -0
- data/spec/orange-core/mock/mock_app.rb +16 -0
- data/spec/orange-core/mock/mock_carton.rb +43 -0
- data/spec/orange-core/mock/mock_core.rb +2 -0
- data/spec/orange-core/mock/mock_middleware.rb +25 -0
- data/spec/orange-core/mock/mock_mixins.rb +19 -0
- data/spec/orange-core/mock/mock_model_resource.rb +47 -0
- data/spec/orange-core/mock/mock_pulp.rb +24 -0
- data/spec/orange-core/mock/mock_resource.rb +26 -0
- data/spec/orange-core/mock/mock_router.rb +10 -0
- data/spec/orange-core/orange_spec.rb +19 -0
- data/spec/orange-core/packet_spec.rb +203 -0
- data/spec/orange-core/resource_spec.rb +96 -0
- data/spec/orange-core/resources/mapper_spec.rb +5 -0
- data/spec/orange-core/resources/model_resource_spec.rb +246 -0
- data/spec/orange-core/resources/parser_spec.rb +5 -0
- data/spec/orange-core/resources/routable_resource_spec.rb +5 -0
- data/spec/orange-core/spec_helper.rb +53 -0
- data/spec/orange-core/stack_spec.rb +232 -0
- data/spec/stats.rb +182 -0
- metadata +227 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'orange-core/resource'
|
2
|
+
module Orange
|
3
|
+
class PageParts < Resource
|
4
|
+
def afterLoad
|
5
|
+
orange.add_pulp Orange::Pulp::PageParts
|
6
|
+
end
|
7
|
+
|
8
|
+
def part(packet)
|
9
|
+
unless packet[:page_parts, false]
|
10
|
+
packet[:page_parts] = DefaultHash.new
|
11
|
+
packet[:page_parts].default = ''
|
12
|
+
end
|
13
|
+
packet[:page_parts]
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def add_css(packet, file, opts = {})
|
18
|
+
ie = opts[:ie] || false
|
19
|
+
mod = opts[:module] || 'public'
|
20
|
+
# module set to false gives the root assets dir
|
21
|
+
assets = File.join('assets', mod)
|
22
|
+
file = File.join('', assets, 'css', file)
|
23
|
+
unless packet[:css_files, []].include?(file)
|
24
|
+
if ie
|
25
|
+
part(packet)[:ie_css] = part(packet)[:ie_css] + "<link rel=\"stylesheet\" href=\"#{file}\" type=\"text/css\" media=\"screen\" charset=\"utf-8\" />"
|
26
|
+
else
|
27
|
+
part(packet)[:css] = part(packet)[:css] + "<link rel=\"stylesheet\" href=\"#{file}\" type=\"text/css\" media=\"screen\" charset=\"utf-8\" />"
|
28
|
+
end
|
29
|
+
packet[:css_files] ||= []
|
30
|
+
packet[:css_files].insert((opts[:position] ? opts[:position] : -1), file)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_js(packet, file, opts = {})
|
35
|
+
ie = opts[:ie] || false
|
36
|
+
mod = opts[:module] || 'public'
|
37
|
+
assets = File.join('assets', mod)
|
38
|
+
file = File.join('', assets, 'js', file)
|
39
|
+
unless packet[:js_files, []].include?(file)
|
40
|
+
if ie
|
41
|
+
part(packet)[:ie_js] = part(packet)[:ie_js] + "<script src=\"#{file}\" type=\"text/javascript\"></script>"
|
42
|
+
else
|
43
|
+
part(packet)[:js] = part(packet)[:js] + "<script src=\"#{file}\" type=\"text/javascript\"></script>"
|
44
|
+
end
|
45
|
+
packet[:js_files] ||= []
|
46
|
+
packet[:js_files].insert((opts[:position] ? opts[:position] : -1), file)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
module Pulp::PageParts
|
52
|
+
def part
|
53
|
+
orange[:page_parts].part(packet)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Feels like part should be plural, no?
|
57
|
+
def parts; part; end
|
58
|
+
|
59
|
+
|
60
|
+
def add_css(file, opts = {})
|
61
|
+
orange[:page_parts].add_css(packet, file, opts)
|
62
|
+
end
|
63
|
+
|
64
|
+
def add_js(file, opts = {})
|
65
|
+
orange[:page_parts].add_js(packet, file, opts)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'orange-core/core'
|
2
|
+
require 'haml'
|
3
|
+
require 'yaml'
|
4
|
+
require 'crack'
|
5
|
+
|
6
|
+
module Orange
|
7
|
+
class Parser < Resource
|
8
|
+
def afterLoad
|
9
|
+
orange.add_pulp Orange::Pulp::ParserPulp
|
10
|
+
@template_dirs = [File.join(orange.core_dir, 'templates')]
|
11
|
+
@view_dirs = [File.join(orange.core_dir, 'views')]
|
12
|
+
Orange.plugins.each{|p| @template_dirs << p.templates if p.has_templates? }
|
13
|
+
Orange.plugins.each{|p| @view_dirs << p.views if p.has_views? }
|
14
|
+
end
|
15
|
+
|
16
|
+
def yaml(file)
|
17
|
+
return nil unless File.exists?(file)
|
18
|
+
string = File.read(file)
|
19
|
+
string.gsub!('__ORANGE__', orange.app_dir)
|
20
|
+
out = YAML::load(string)
|
21
|
+
end
|
22
|
+
|
23
|
+
def haml(file, packet_binding, *vars, &block)
|
24
|
+
|
25
|
+
opts = vars.extract_options!
|
26
|
+
# Initial info
|
27
|
+
temp = opts.delete(:template)
|
28
|
+
opts[:resource_name] = opts[:resource].orange_name.to_s if
|
29
|
+
opts[:resource] && opts[:resource].respond_to?(:orange_name)
|
30
|
+
resource = (opts[:resource_name] || '').downcase
|
31
|
+
|
32
|
+
if packet_binding.is_a? Orange::Packet
|
33
|
+
context = packet_binding['route.context'].to_s
|
34
|
+
unless temp
|
35
|
+
packet_binding['parser.haml-templates'] ||= {}
|
36
|
+
haml_engine = packet_binding['parser.haml-templates']["#{context}-#{resource}-#{file}"] || false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
unless haml_engine
|
40
|
+
opts.merge :orange => orange
|
41
|
+
|
42
|
+
string = false
|
43
|
+
if temp
|
44
|
+
string ||= read_if_exists('templates', file)
|
45
|
+
@template_dirs.each do |templates_dir|
|
46
|
+
string ||= read_if_exists(templates_dir, file)
|
47
|
+
end unless string
|
48
|
+
end
|
49
|
+
|
50
|
+
if context
|
51
|
+
#Check for context specific overrides
|
52
|
+
string ||= read_if_exists('views', resource, context+"."+file) if resource
|
53
|
+
string ||= read_if_exists('views', context+"."+file)
|
54
|
+
@view_dirs.each do |views_dir|
|
55
|
+
string ||= read_if_exists(views_dir, resource, context+"."+file) if resource
|
56
|
+
string ||= read_if_exists(views_dir, context+"."+file)
|
57
|
+
end unless string
|
58
|
+
end
|
59
|
+
|
60
|
+
# Check for standard views
|
61
|
+
string ||= read_if_exists('views', resource, file) if resource
|
62
|
+
string ||= read_if_exists('views', file)
|
63
|
+
@view_dirs.each do |views_dir|
|
64
|
+
string ||= read_if_exists(views_dir, resource, file) if resource
|
65
|
+
string ||= read_if_exists(views_dir, file)
|
66
|
+
end unless string
|
67
|
+
|
68
|
+
# Check for default resource views
|
69
|
+
string ||= read_if_exists('views', 'default_resource', file)
|
70
|
+
@view_dirs.each do |views_dir|
|
71
|
+
string ||= read_if_exists(views_dir, 'default_resource', file) if resource
|
72
|
+
end unless string
|
73
|
+
raise LoadError, "Couldn't find haml file '#{file}'" unless string
|
74
|
+
|
75
|
+
haml_engine = Haml::Engine.new(string)
|
76
|
+
if packet_binding.is_a? Orange::Packet
|
77
|
+
packet_binding['parser.haml-templates']["#{context}-#{resource}-#{file}"] = haml_engine
|
78
|
+
end
|
79
|
+
end
|
80
|
+
out = haml_engine.render(packet_binding, opts, &block)
|
81
|
+
end
|
82
|
+
|
83
|
+
def read_if_exists(*args)
|
84
|
+
return File.read(File.join(*args)) if File.exists?(File.join(*args))
|
85
|
+
false
|
86
|
+
end
|
87
|
+
|
88
|
+
def hpricot(text)
|
89
|
+
require 'hpricot'
|
90
|
+
Hpricot(text)
|
91
|
+
end
|
92
|
+
|
93
|
+
def xml(text)
|
94
|
+
Crack::XML.parse(text)
|
95
|
+
end
|
96
|
+
|
97
|
+
def json(text)
|
98
|
+
Crack::JSON.parse(text)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
module Pulp::ParserPulp
|
103
|
+
def html(&block)
|
104
|
+
if block_given?
|
105
|
+
unless(packet[:content].blank?)
|
106
|
+
doc = orange[:parser].hpricot(packet[:content])
|
107
|
+
yield doc
|
108
|
+
packet[:content] = doc.to_s
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'orange-core/resource'
|
2
|
+
|
3
|
+
module Orange
|
4
|
+
class RoutableResource < Resource
|
5
|
+
def routable; true; end
|
6
|
+
|
7
|
+
def route(path, packet)
|
8
|
+
parts = path.split('/')
|
9
|
+
first = parts[0].respond_to?(:to_sym) ? parts.shift.to_sym : :index
|
10
|
+
new_path = parts.join('/')
|
11
|
+
if self.respond_to?(first)
|
12
|
+
packet[:content] = self.__send__(first, new_path, packet)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'orange-core/core'
|
2
|
+
|
3
|
+
module Orange
|
4
|
+
class Scaffold < Resource
|
5
|
+
# Load the scaffold helpers
|
6
|
+
def afterLoad
|
7
|
+
orange.add_pulp Pulp::ScaffoldHelpers
|
8
|
+
Packet.meta_methods(/view_([a-zA-Z_]+)/) do |packet, match, args|
|
9
|
+
model = args.shift
|
10
|
+
args = args.extract_with_defaults(:mode => match[1].to_sym)
|
11
|
+
packet.view(model, args)
|
12
|
+
end
|
13
|
+
@scaffold_types = {}
|
14
|
+
add_scaffold_type(:boolean) do |name, val, opts|
|
15
|
+
if opts[:show]
|
16
|
+
val ? "true" : "false"
|
17
|
+
else
|
18
|
+
ret = "<input type='hidden' name='#{opts[:model_name]}[#{name}]' value='0' /><input type='checkbox' name='#{opts[:model_name]}[#{name}]' value='1' #{'checked="checked"' if (val && val != '')}/>"
|
19
|
+
ret = "<label for=''>#{opts[:display_name]}</label><br />" + ret if opts[:label]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_scaffold_type(type, &block)
|
25
|
+
@scaffold_types[type] = Proc.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def scaffold_attribute(packet, prop, model_name, *args)
|
29
|
+
args = args.extract_options!
|
30
|
+
args.with_defaults!({:packet => packet, :value => '', :label => false, :show => false})
|
31
|
+
val = args[:value]
|
32
|
+
label = args[:label]
|
33
|
+
show = args[:show]
|
34
|
+
name = prop[:name]
|
35
|
+
human_readable_name = name.to_s.split('_').each{|w| w.capitalize!}.join(' ')
|
36
|
+
display_name = prop[:display_name] || human_readable_name
|
37
|
+
return @scaffold_types[prop[:type]].call(name, val, args.with_defaults!(:display_name => display_name, :model_name => model_name)) if @scaffold_types.has_key?(prop[:type])
|
38
|
+
unless show
|
39
|
+
case prop[:type]
|
40
|
+
when :title
|
41
|
+
val.gsub!('"', '"')
|
42
|
+
ret = "<input class=\"title\" type=\"text\" value=\"#{val}\" name=\"#{model_name}[#{name}]\" />"
|
43
|
+
when :text
|
44
|
+
val.gsub!('"', '"')
|
45
|
+
ret = "<input type=\"text\" value=\"#{val}\" name=\"#{model_name}[#{name}]\" />"
|
46
|
+
when :fulltext
|
47
|
+
ret = "<textarea name='#{model_name}[#{name}]'>#{val}</textarea>"
|
48
|
+
when :boolean
|
49
|
+
human_readable_name = human_readable_name + '?'
|
50
|
+
ret = "<input type='hidden' name='#{model_name}[#{name}]' value='0' /><input type='checkbox' name='#{model_name}[#{name}]' value='1' #{'checked="checked"' if (val && val != '')}/>"
|
51
|
+
when :date
|
52
|
+
val.gsub!('"', '"')
|
53
|
+
ret = "<input class=\"date\" type=\"text\" value=\"#{val}\" name=\"#{model_name}[#{name}]\" />"
|
54
|
+
else
|
55
|
+
val.gsub!('"', '"')
|
56
|
+
ret = "<input type=\"text\" value=\"#{val}\" name=\"#{model_name}[#{name}]\" />"
|
57
|
+
end
|
58
|
+
ret = "<label for=''>#{display_name}</label><br />" + ret if label
|
59
|
+
else
|
60
|
+
case prop[:type]
|
61
|
+
when :title
|
62
|
+
ret = "<h3 class='#{model_name}-#{name}'>#{val}</h3>"
|
63
|
+
when :text
|
64
|
+
ret = "<p class='#{model_name}-#{name}'>#{val}</p>"
|
65
|
+
when :fulltext
|
66
|
+
ret = "<div class='#{model_name}-#{name}'>#{val}</div>"
|
67
|
+
else
|
68
|
+
ret = "<div class='#{model_name}-#{name}'>#{val}</div>"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
return ret
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
module Pulp::ScaffoldHelpers
|
76
|
+
# Creates a button that appears to be a link but
|
77
|
+
# does form submission with custom method (_method param in POST)
|
78
|
+
# This is to avoid issues of a destructive get.
|
79
|
+
# @param [String] text link text to show
|
80
|
+
# @param [String] link the actual href value of the link
|
81
|
+
# @param [String, false] confirm text of the javascript confirm (false for none [default])
|
82
|
+
# @param [optional, Array] args array of optional arguments, only opts[:method] defined
|
83
|
+
# @option opts [String] method method name (Should be 'DELETE', 'PUT' or 'POST')
|
84
|
+
def form_link(text, link, confirm = false, opts = {})
|
85
|
+
text = "<img src='#{opts[:img]}' alt='#{text}' />" if opts[:img]
|
86
|
+
css = opts[:class]? opts[:class] : 'form_button_link'
|
87
|
+
meth = (opts[:method]? "<input type='hidden' name='_method' value='#{opts[:method]}' />" : '')
|
88
|
+
if confirm
|
89
|
+
"<form action='#{link}' method='post' class='mini' onsubmit='return confirm(\"#{confirm}\")'><button class='link_button'><a href='#' class='#{css}'>#{text}</a></button>#{meth}</form>"
|
90
|
+
else
|
91
|
+
"<form action='#{link}' method='post' class='mini'><button class='link_button'><a href='#' class='#{css}'>#{text}</a></button>#{meth}</form>"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Calls view for an orange resource.
|
96
|
+
def view(model_name, *args)
|
97
|
+
orange[model_name].view(self, *args)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns a scaffolded attribute
|
101
|
+
def view_attribute(prop, model_name, *args)
|
102
|
+
orange[:scaffold].scaffold_attribute(self, prop, model_name, *args)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
require 'orange-core/core'
|
2
|
+
require 'rack/builder'
|
3
|
+
module Orange
|
4
|
+
# Builds an orange stack of middleware
|
5
|
+
# Use in the rackup file as follows:
|
6
|
+
# app = Orange::Stack.new do
|
7
|
+
# stack Orange::DataMapper 'sqlite3::memory:' <= loads orange specific middleware
|
8
|
+
# use OtherMiddleware
|
9
|
+
# run SomeApp.new
|
10
|
+
# end
|
11
|
+
# run app
|
12
|
+
#
|
13
|
+
# All middleware placed inside the Orange::Stack will have access
|
14
|
+
# to the Orange Core (as long as it's been written to accept it as the second
|
15
|
+
# initialization argument) when added with the 'stack' method
|
16
|
+
#
|
17
|
+
# In general, Orange::Stack works like Rack::Builder.
|
18
|
+
class Stack
|
19
|
+
|
20
|
+
# Creates a new Orange::Stack out of the passed block.
|
21
|
+
#
|
22
|
+
# If a block is not passed, it will try to build one from scratch.
|
23
|
+
# The bare minimum will be `run app_class.new(@core)`, there are also
|
24
|
+
# other stacks that can be used.
|
25
|
+
#
|
26
|
+
# @param [Orange::Application] app_class the class of the main application
|
27
|
+
# @param [Orange::Core] core the orange core
|
28
|
+
# @param [Symbol] prebuilt the optional prebuilt stack, if one isn't passed as block
|
29
|
+
def initialize(app_class = nil, core = false, prebuilt = :none, &block)
|
30
|
+
@build = Rack::Builder.new
|
31
|
+
@core = core || Orange::Core.new
|
32
|
+
@core.stack = self # Set a back reference in the core.
|
33
|
+
@auto_reload = false
|
34
|
+
@app = false
|
35
|
+
@middleware = []
|
36
|
+
@recapture = true
|
37
|
+
@main_app = app_class
|
38
|
+
if block_given?
|
39
|
+
instance_eval(&block)
|
40
|
+
else
|
41
|
+
@main_app = app_class.new(@core) unless app_class.nil?
|
42
|
+
prebuild(prebuilt)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Runs methods necessary to build a stack. Don't use if a stack
|
47
|
+
# has already been built by the initialize block.
|
48
|
+
#
|
49
|
+
# @todo Offer more choices for default stacks
|
50
|
+
def prebuild(choice)
|
51
|
+
case choice
|
52
|
+
when :none
|
53
|
+
run @main_app
|
54
|
+
else
|
55
|
+
run @main_app
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns the main application instance that was added by the
|
60
|
+
# run method. Obviously won't return anything useful if the
|
61
|
+
# middleware stack hasn't been set up with an explicit exit point,
|
62
|
+
# as could be the case for a pure orange middleware stack on
|
63
|
+
# top of a different exit application (like Sinatra or Rails)
|
64
|
+
def main_app
|
65
|
+
@main_app
|
66
|
+
end
|
67
|
+
|
68
|
+
# Adds middleware using the Rack::Builder#use method
|
69
|
+
# @param [Object] middleware A class of middleware that meets rack middleware requirements
|
70
|
+
def use(middleware, *args, &block)
|
71
|
+
@build.use(middleware, *args, &block)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Loads resources into the core using the Orange::Core#load method
|
75
|
+
#
|
76
|
+
# all args are passed on
|
77
|
+
def load(*args, &block)
|
78
|
+
orange.load(*args, &block)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Adds Orange-aware middleware using the Rack::Builder#use method, adding
|
82
|
+
# the orange core to the args passed on
|
83
|
+
def stack(middleware, *args, &block)
|
84
|
+
@build.use(middleware, @core, *args, &block)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Set the auto_reload option, called without args, defaults to true,
|
88
|
+
# other option is to set it to false
|
89
|
+
def auto_reload!(val = true)
|
90
|
+
@auto_reload = val
|
91
|
+
end
|
92
|
+
|
93
|
+
# Shortcut for adding Orange::Middleware::ShowExceptions to the middleware
|
94
|
+
# stack
|
95
|
+
def use_exceptions
|
96
|
+
stack Orange::Middleware::ShowExceptions
|
97
|
+
end
|
98
|
+
|
99
|
+
# Alias for use_exceptions
|
100
|
+
def show_exceptions
|
101
|
+
use_exceptions
|
102
|
+
end
|
103
|
+
|
104
|
+
# Turn off recapture middleware, which is normally just on top of the exit
|
105
|
+
# point
|
106
|
+
# @see Orange::Middleware::Recapture
|
107
|
+
def no_recapture
|
108
|
+
@recapture = false
|
109
|
+
end
|
110
|
+
|
111
|
+
# A shortcut for adding many of the routing middleware options
|
112
|
+
# simultaneously. Includes:
|
113
|
+
# * Orange::Middleware::Rerouter
|
114
|
+
# * Orange::Middleware::Static
|
115
|
+
# * Rack::AbstractFormat
|
116
|
+
# * Orange::Middleware::RouteSite
|
117
|
+
# * Orange::Middleware::RouteContext
|
118
|
+
#
|
119
|
+
# All of these are passed the args hash to use as they will, except
|
120
|
+
# for Rack::AbstractFormat
|
121
|
+
#
|
122
|
+
def prerouting(*args)
|
123
|
+
opts = args.extract_options!
|
124
|
+
stack Orange::Middleware::Globals
|
125
|
+
stack Orange::Middleware::Loader
|
126
|
+
stack Orange::Middleware::Rerouter, opts.dup
|
127
|
+
stack Orange::Middleware::Static, opts.dup
|
128
|
+
use Rack::AbstractFormat unless opts[:no_abstract_format]
|
129
|
+
# Must be used before non-destructive route altering done by Orange,
|
130
|
+
# since all orange stuff is non-destructive
|
131
|
+
stack Orange::Middleware::RouteSite, opts.dup
|
132
|
+
stack Orange::Middleware::RouteContext, opts.dup
|
133
|
+
stack Orange::Middleware::Database
|
134
|
+
Orange.plugins.each{|p| p.middleware(:prerouting).each{|m| stack m, opts.dup} if p.has_middleware?}
|
135
|
+
end
|
136
|
+
|
137
|
+
# A shortcut for routing via Orange::Middleware::RestfulRouter and any plugins
|
138
|
+
#
|
139
|
+
# Any args are passed on to the middleware
|
140
|
+
def routing(opts ={})
|
141
|
+
stack Orange::Middleware::RestfulRouter, opts.dup
|
142
|
+
Orange.plugins.each{|p| p.middleware(:routing).each{|m| stack m, opts.dup} if p.has_middleware?}
|
143
|
+
end
|
144
|
+
|
145
|
+
def postrouting(opts ={})
|
146
|
+
Orange.plugins.each{|p| p.middleware(:postrouting).each{|m| stack m, opts.dup} if p.has_middleware?}
|
147
|
+
stack Orange::Middleware::Template
|
148
|
+
stack Orange::Middleware::FourOhFour, opts.dup # Last ditch, send route to 404 page.
|
149
|
+
end
|
150
|
+
|
151
|
+
def responders(opts ={})
|
152
|
+
Orange.plugins.each{|p| p.middleware(:responders).each{|m| stack m, opts.dup} if p.has_middleware?}
|
153
|
+
end
|
154
|
+
|
155
|
+
# # A shortcut to enable Rack::OpenID and Orange::Middleware::AccessControl
|
156
|
+
# #
|
157
|
+
# # Args will be passed on to Orange::Middleware::AccessControl
|
158
|
+
# def openid_access_control(*args)
|
159
|
+
# opts = args.extract_options!
|
160
|
+
#
|
161
|
+
# end
|
162
|
+
|
163
|
+
# Adds pulp to the core via the Orange::Core#add_pulp method
|
164
|
+
# @param [Orange::Mixin] mod a mixin to be included in the packet
|
165
|
+
def add_pulp(mod)
|
166
|
+
orange.add_pulp(mod)
|
167
|
+
end
|
168
|
+
|
169
|
+
# The exit point for the middleware stack,
|
170
|
+
# add the app to @main_app and then call Rack::Builder#run with the main app
|
171
|
+
def run(app, *args)
|
172
|
+
opts = args.extract_options!
|
173
|
+
@main_app = app
|
174
|
+
@build.run(app)
|
175
|
+
end
|
176
|
+
|
177
|
+
# Returns the Orange::Core
|
178
|
+
# @return [Orange::Core] The orange core
|
179
|
+
def orange
|
180
|
+
@core
|
181
|
+
end
|
182
|
+
|
183
|
+
# Passes through to Rack::Builder#map
|
184
|
+
# @todo Make this work - passing the block on to builder
|
185
|
+
# means we can't intercept anything, which will yield
|
186
|
+
# unexpected results
|
187
|
+
def map(path, &block)
|
188
|
+
raise 'not yet supported'
|
189
|
+
@build.map(path, &block)
|
190
|
+
end
|
191
|
+
|
192
|
+
# Builds the middleware stack (or uses a cached one)
|
193
|
+
#
|
194
|
+
# If auto_reload is enabled ({#auto_reload!}), builds every time
|
195
|
+
#
|
196
|
+
# @return [Object] a full stack of middleware and the exit application,
|
197
|
+
# conforming to Rack guidelines
|
198
|
+
def app
|
199
|
+
if @auto_reload
|
200
|
+
orange.fire(:stack_reloading, @app) if orange.stack # Alert we are rebuilding
|
201
|
+
@app = false # Rebuild no matter what if autoload
|
202
|
+
end
|
203
|
+
unless @app
|
204
|
+
@app = do_build # Build if necessary
|
205
|
+
orange.fire(:stack_loaded, @app)
|
206
|
+
end
|
207
|
+
@app
|
208
|
+
end
|
209
|
+
|
210
|
+
def do_build
|
211
|
+
@build.to_app
|
212
|
+
end
|
213
|
+
|
214
|
+
# Sets the core and then passes on to the stack, according to standard
|
215
|
+
# rack procedure
|
216
|
+
def call(env)
|
217
|
+
env['orange.core'] = @core
|
218
|
+
app.call(env)
|
219
|
+
end
|
220
|
+
|
221
|
+
# Debug helping
|
222
|
+
def inspect
|
223
|
+
"#<Orange::Stack:0x#{self.object_id.to_s(16)} @build=#{@build.inspect}, @core=#{@core.inspect}>"
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|