raw 0.49.0
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/doc/CONTRIBUTORS +106 -0
- data/doc/LICENSE +32 -0
- data/doc/coding_conventions.txt +11 -0
- data/lib/raw.rb +42 -0
- data/lib/raw/adapter.rb +113 -0
- data/lib/raw/adapter/cgi.rb +41 -0
- data/lib/raw/adapter/fastcgi.rb +48 -0
- data/lib/raw/adapter/mongrel.rb +146 -0
- data/lib/raw/adapter/script.rb +94 -0
- data/lib/raw/adapter/webrick.rb +144 -0
- data/lib/raw/adapter/webrick/vcr.rb +91 -0
- data/lib/raw/cgi.rb +323 -0
- data/lib/raw/cgi/cookie.rb +47 -0
- data/lib/raw/cgi/http.rb +62 -0
- data/lib/raw/compiler.rb +138 -0
- data/lib/raw/compiler/filter/cleanup.rb +21 -0
- data/lib/raw/compiler/filter/elements.rb +166 -0
- data/lib/raw/compiler/filter/elements/element.rb +210 -0
- data/lib/raw/compiler/filter/localization.rb +23 -0
- data/lib/raw/compiler/filter/markup.rb +32 -0
- data/lib/raw/compiler/filter/morph.rb +123 -0
- data/lib/raw/compiler/filter/morph/each.rb +34 -0
- data/lib/raw/compiler/filter/morph/for.rb +11 -0
- data/lib/raw/compiler/filter/morph/if.rb +26 -0
- data/lib/raw/compiler/filter/morph/selected_if.rb +43 -0
- data/lib/raw/compiler/filter/morph/standard.rb +55 -0
- data/lib/raw/compiler/filter/morph/times.rb +27 -0
- data/lib/raw/compiler/filter/script.rb +116 -0
- data/lib/raw/compiler/filter/squeeze.rb +16 -0
- data/lib/raw/compiler/filter/static_include.rb +74 -0
- data/lib/raw/compiler/filter/template.rb +121 -0
- data/lib/raw/compiler/reloader.rb +96 -0
- data/lib/raw/context.rb +154 -0
- data/lib/raw/context/flash.rb +157 -0
- data/lib/raw/context/global.rb +88 -0
- data/lib/raw/context/request.rb +338 -0
- data/lib/raw/context/response.rb +57 -0
- data/lib/raw/context/session.rb +198 -0
- data/lib/raw/context/session/drb.rb +11 -0
- data/lib/raw/context/session/file.rb +15 -0
- data/lib/raw/context/session/memcached.rb +13 -0
- data/lib/raw/context/session/memory.rb +12 -0
- data/lib/raw/context/session/og.rb +15 -0
- data/lib/raw/context/session/pstore.rb +13 -0
- data/lib/raw/control.rb +18 -0
- data/lib/raw/control/attribute.rb +91 -0
- data/lib/raw/control/attribute/checkbox.rb +25 -0
- data/lib/raw/control/attribute/datetime.rb +21 -0
- data/lib/raw/control/attribute/file.rb +20 -0
- data/lib/raw/control/attribute/fixnum.rb +26 -0
- data/lib/raw/control/attribute/float.rb +26 -0
- data/lib/raw/control/attribute/options.rb +38 -0
- data/lib/raw/control/attribute/password.rb +16 -0
- data/lib/raw/control/attribute/text.rb +16 -0
- data/lib/raw/control/attribute/textarea.rb +16 -0
- data/lib/raw/control/none.rb +16 -0
- data/lib/raw/control/relation.rb +59 -0
- data/lib/raw/control/relation/belongs_to.rb +0 -0
- data/lib/raw/control/relation/has_many.rb +97 -0
- data/lib/raw/control/relation/joins_many.rb +0 -0
- data/lib/raw/control/relation/many_to_many.rb +0 -0
- data/lib/raw/control/relation/refers_to.rb +29 -0
- data/lib/raw/controller.rb +37 -0
- data/lib/raw/controller/publishable.rb +160 -0
- data/lib/raw/dispatcher.rb +209 -0
- data/lib/raw/dispatcher/format.rb +108 -0
- data/lib/raw/dispatcher/format/atom.rb +31 -0
- data/lib/raw/dispatcher/format/css.rb +0 -0
- data/lib/raw/dispatcher/format/html.rb +42 -0
- data/lib/raw/dispatcher/format/json.rb +31 -0
- data/lib/raw/dispatcher/format/rss.rb +33 -0
- data/lib/raw/dispatcher/format/xoxo.rb +31 -0
- data/lib/raw/dispatcher/mounter.rb +60 -0
- data/lib/raw/dispatcher/router.rb +111 -0
- data/lib/raw/errors.rb +19 -0
- data/lib/raw/helper.rb +86 -0
- data/lib/raw/helper/benchmark.rb +23 -0
- data/lib/raw/helper/buffer.rb +60 -0
- data/lib/raw/helper/cookie.rb +32 -0
- data/lib/raw/helper/debug.rb +28 -0
- data/lib/raw/helper/default.rb +16 -0
- data/lib/raw/helper/feed.rb +451 -0
- data/lib/raw/helper/form.rb +284 -0
- data/lib/raw/helper/javascript.rb +59 -0
- data/lib/raw/helper/layout.rb +40 -0
- data/lib/raw/helper/navigation.rb +87 -0
- data/lib/raw/helper/pager.rb +305 -0
- data/lib/raw/helper/table.rb +247 -0
- data/lib/raw/helper/xhtml.rb +218 -0
- data/lib/raw/helper/xml.rb +125 -0
- data/lib/raw/mixin/magick.rb +35 -0
- data/lib/raw/mixin/sweeper.rb +71 -0
- data/lib/raw/mixin/thumbnails.rb +1 -0
- data/lib/raw/mixin/webfile.rb +165 -0
- data/lib/raw/render.rb +271 -0
- data/lib/raw/render/builder.rb +26 -0
- data/lib/raw/render/caching.rb +81 -0
- data/lib/raw/render/call.rb +43 -0
- data/lib/raw/render/send_file.rb +46 -0
- data/lib/raw/render/stream.rb +39 -0
- data/lib/raw/scaffold.rb +13 -0
- data/lib/raw/scaffold/controller.rb +25 -0
- data/lib/raw/scaffold/model.rb +157 -0
- data/lib/raw/test.rb +5 -0
- data/lib/raw/test/assertions.rb +169 -0
- data/lib/raw/test/context.rb +55 -0
- data/lib/raw/test/testcase.rb +79 -0
- data/lib/raw/util/attr.rb +128 -0
- data/lib/raw/util/encode_uri.rb +149 -0
- data/lib/raw/util/html_filter.rb +538 -0
- data/lib/raw/util/markup.rb +130 -0
- data/test/glue/tc_webfile.rb +1 -0
- data/test/nitro/CONFIG.rb +3 -0
- data/test/nitro/adapter/raw_post1.bin +9 -0
- data/test/nitro/adapter/tc_webrick.rb +16 -0
- data/test/nitro/cgi/tc_cookie.rb +14 -0
- data/test/nitro/cgi/tc_request.rb +61 -0
- data/test/nitro/compiler/tc_client_morpher.rb +47 -0
- data/test/nitro/compiler/tc_compiler.rb +25 -0
- data/test/nitro/dispatcher/tc_mounter.rb +47 -0
- data/test/nitro/helper/tc_feed.rb +135 -0
- data/test/nitro/helper/tc_navbar.rb +74 -0
- data/test/nitro/helper/tc_pager.rb +35 -0
- data/test/nitro/helper/tc_table.rb +68 -0
- data/test/nitro/helper/tc_xhtml.rb +19 -0
- data/test/nitro/tc_caching.rb +19 -0
- data/test/nitro/tc_cgi.rb +222 -0
- data/test/nitro/tc_context.rb +17 -0
- data/test/nitro/tc_controller.rb +103 -0
- data/test/nitro/tc_controller_aspect.rb +32 -0
- data/test/nitro/tc_controller_params.rb +885 -0
- data/test/nitro/tc_dispatcher.rb +109 -0
- data/test/nitro/tc_element.rb +85 -0
- data/test/nitro/tc_flash.rb +59 -0
- data/test/nitro/tc_helper.rb +47 -0
- data/test/nitro/tc_render.rb +119 -0
- data/test/nitro/tc_router.rb +61 -0
- data/test/nitro/tc_server.rb +35 -0
- data/test/nitro/tc_session.rb +66 -0
- data/test/nitro/tc_template.rb +71 -0
- data/test/nitro/util/tc_encode_url.rb +87 -0
- data/test/nitro/util/tc_markup.rb +31 -0
- data/test/public/blog/another/very_litle/index.xhtml +1 -0
- data/test/public/blog/inc1.xhtml +2 -0
- data/test/public/blog/inc2.xhtml +1 -0
- data/test/public/blog/list.xhtml +9 -0
- data/test/public/dummy_mailer/registration.xhtml +5 -0
- metadata +244 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "raw/mixin/magick"
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
require "fileutils"
|
|
2
|
+
|
|
3
|
+
require "facets/more/inheritor"
|
|
4
|
+
|
|
5
|
+
module Raw::Mixin
|
|
6
|
+
|
|
7
|
+
# A Web File.
|
|
8
|
+
#
|
|
9
|
+
# You can customize the path where the uploaded file will be
|
|
10
|
+
# by defining a webfile_path class method *before* the property:
|
|
11
|
+
#
|
|
12
|
+
# class Icon
|
|
13
|
+
# def self.webfile_path request, name
|
|
14
|
+
# File.join(Uploads.public_root, request.user.name, 'icon.png')
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# attr_accessor :file, WebFile, :magick => { :small => '64x64', :medium => '96x96' }
|
|
18
|
+
# end
|
|
19
|
+
#--
|
|
20
|
+
# TODO: webfile_path customization sucks, should be improved!
|
|
21
|
+
#++
|
|
22
|
+
|
|
23
|
+
class WebFile
|
|
24
|
+
|
|
25
|
+
# The directory where uploaded files are stored. Typically
|
|
26
|
+
# this is a symlink to another directory outside of the
|
|
27
|
+
# webapp dir for easier updates.
|
|
28
|
+
|
|
29
|
+
setting :upload_root, :default => 'upload', :doc => 'The directory where upload files are stored'
|
|
30
|
+
|
|
31
|
+
# Override files by default?
|
|
32
|
+
|
|
33
|
+
setting :override_files, :default => true, :doc => 'Override files by default?'
|
|
34
|
+
|
|
35
|
+
# Modify the base class when this class is included as a
|
|
36
|
+
# property
|
|
37
|
+
#--
|
|
38
|
+
# TODO: find a better name.
|
|
39
|
+
#++
|
|
40
|
+
|
|
41
|
+
def self.included_as_property(base, args)
|
|
42
|
+
if args.last.is_a?(Hash)
|
|
43
|
+
options = args.pop
|
|
44
|
+
else
|
|
45
|
+
options = Hash.new
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
args.pop if args.last.is_a?(Class)
|
|
49
|
+
|
|
50
|
+
if thumbnails = (options[:thumbnail] || options[:thumbnails] || options[:magick]) or self.name == 'WebImage'
|
|
51
|
+
require 'glue/thumbnails'
|
|
52
|
+
base.send :include, Thumbnails
|
|
53
|
+
thumbnails = { :small => :thumbnails } if thumbnails.is_a?(String)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
for name in args
|
|
57
|
+
base.module_eval do
|
|
58
|
+
# The 'web' path to the file (relative to the public
|
|
59
|
+
# root directory. Uses the original property name
|
|
60
|
+
# or the #{name}_path alias.
|
|
61
|
+
|
|
62
|
+
attr_accessor name.to_sym, String, :control => :file
|
|
63
|
+
alias_method "#{name}_path".to_sym, name.to_sym
|
|
64
|
+
|
|
65
|
+
# The file size.
|
|
66
|
+
|
|
67
|
+
attr_accessor "#{name}_size".to_sym, Fixnum, :control => :none
|
|
68
|
+
|
|
69
|
+
# The mime type.
|
|
70
|
+
|
|
71
|
+
attr_accessor "#{name}_mime_type".to_sym, String , :control => :none
|
|
72
|
+
|
|
73
|
+
# Assignment callbacks.
|
|
74
|
+
#--
|
|
75
|
+
# gmosx, FIXME: this is a hack!! better implementation
|
|
76
|
+
# is needed (generalized property assigners).
|
|
77
|
+
|
|
78
|
+
inheritor(:assign_callbacks, [], :merge) unless @assign_callbacks
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
if thumbnails
|
|
82
|
+
for tname in thumbnails.keys
|
|
83
|
+
base.module_eval do
|
|
84
|
+
attr_accessor "#{name}_#{tname}_thumbnail".to_sym, String, :control => :none
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
code = %{
|
|
90
|
+
def #{name}_real_path
|
|
91
|
+
File.join(Nitro::Server.public_root, @#{name})
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def #{name}_from_request(request)
|
|
95
|
+
param = request['#{name}']
|
|
96
|
+
|
|
97
|
+
return if param.nil? or param.original_filename.blank?
|
|
98
|
+
}
|
|
99
|
+
if base.respond_to? :webfile_path
|
|
100
|
+
code << %{
|
|
101
|
+
path = #{base}.webfile_path(request, '#{name}')
|
|
102
|
+
}
|
|
103
|
+
else
|
|
104
|
+
code << %{
|
|
105
|
+
path = File.join(WebFile.upload_root, WebFile.sanitize(param.original_filename))
|
|
106
|
+
}
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
code << %{
|
|
110
|
+
@#{name} = path
|
|
111
|
+
@#{name}_size = param.size
|
|
112
|
+
|
|
113
|
+
real_path = #{name}_real_path
|
|
114
|
+
raise 'file exists' if !WebFile.override_files and File.exists?(real_path)
|
|
115
|
+
FileUtils.mkdir_p(File.dirname(real_path))
|
|
116
|
+
if param.path
|
|
117
|
+
FileUtils.cp(param.path, real_path)
|
|
118
|
+
else
|
|
119
|
+
# gmosx FIXME: this is a hack!!
|
|
120
|
+
param.rewind
|
|
121
|
+
File.open(real_path, 'wb') { |f| f << param.read }
|
|
122
|
+
end
|
|
123
|
+
FileUtils.chmod(0664, real_path)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if thumbnails
|
|
127
|
+
for tname, geostring in thumbnails
|
|
128
|
+
code << %{
|
|
129
|
+
@#{name}_#{tname}_thumbnail = Thumbnails.generate_thumbnail(path, '#{tname}', '#{geostring}')
|
|
130
|
+
}
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
code << %{
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def delete_#{name}
|
|
138
|
+
FileUtils.rm(#{name}_real_path)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
assign_callbacks! << proc { |obj, values, options|
|
|
142
|
+
obj.#{name}_from_request(values)
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
base.module_eval(code)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Sanitize a filename. You can override this method to make
|
|
151
|
+
# this suit your needs.
|
|
152
|
+
|
|
153
|
+
def self.sanitize(filename)
|
|
154
|
+
ext = File::extname(filename)
|
|
155
|
+
base = File::basename(filename, ext).gsub(/[\\\/\? !@$\(\)]/, '-')[0..64]
|
|
156
|
+
return "#{base}.#{ext}"
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# An alias, implies thumbnailing.
|
|
162
|
+
|
|
163
|
+
WebImage = WebFile
|
|
164
|
+
|
|
165
|
+
end
|
data/lib/raw/render.rb
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
require "stringio"
|
|
2
|
+
|
|
3
|
+
require "facets/core/string/blank"
|
|
4
|
+
require "facets/more/settings"
|
|
5
|
+
|
|
6
|
+
require "raw/render/builder"
|
|
7
|
+
require "raw/render/call"
|
|
8
|
+
|
|
9
|
+
module Raw
|
|
10
|
+
|
|
11
|
+
#--
|
|
12
|
+
# Raise or Throw this exception to stop the current action.
|
|
13
|
+
# Typically called to skip the template. This is considerered
|
|
14
|
+
# a low level tactic. Prefer to use the exit method.
|
|
15
|
+
#++
|
|
16
|
+
|
|
17
|
+
class ActionExit < Exception # :nodoc: all
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#--
|
|
21
|
+
# Raise or Throw this exception to stop rendering altogether.
|
|
22
|
+
# Typically called by redirects.
|
|
23
|
+
#++
|
|
24
|
+
|
|
25
|
+
class RenderExit < Exception # :nodoc: all
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#--
|
|
29
|
+
# The output buffer. The output of a contoller action is
|
|
30
|
+
# accumulated in this buffer before sending this to the client
|
|
31
|
+
# as a HTTP Response.
|
|
32
|
+
#
|
|
33
|
+
# TODO: Implement a FAST string (maybe in C)
|
|
34
|
+
#++
|
|
35
|
+
|
|
36
|
+
class OutputBuffer < String # :nodoc: all
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# The rendering mixin. This module is typically included in
|
|
40
|
+
# published objects and/or controllers to provide rendering
|
|
41
|
+
# functionality.
|
|
42
|
+
|
|
43
|
+
module Render
|
|
44
|
+
|
|
45
|
+
# The output buffer. The output of a script/action is
|
|
46
|
+
# accumulated in this buffer.
|
|
47
|
+
|
|
48
|
+
attr_accessor :out
|
|
49
|
+
alias_method :body, :out
|
|
50
|
+
|
|
51
|
+
# The context.
|
|
52
|
+
|
|
53
|
+
attr_accessor :context
|
|
54
|
+
alias_method :request, :context
|
|
55
|
+
alias_method :response, :context
|
|
56
|
+
|
|
57
|
+
# The name of the currently executing action.
|
|
58
|
+
|
|
59
|
+
attr_accessor :action_name
|
|
60
|
+
|
|
61
|
+
# The current controller class.
|
|
62
|
+
|
|
63
|
+
attr_accessor :controller
|
|
64
|
+
|
|
65
|
+
# Initialize the render.
|
|
66
|
+
#
|
|
67
|
+
# [+context+]
|
|
68
|
+
# A parent render/controller acts as the context.
|
|
69
|
+
|
|
70
|
+
def initialize(context)
|
|
71
|
+
@context = context
|
|
72
|
+
@out = context.output_buffer
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Renders the action denoted by path. The path
|
|
76
|
+
# is resolved by the dispatcher to get the correct
|
|
77
|
+
# controller.
|
|
78
|
+
#
|
|
79
|
+
# Both relative and absolute paths are supported. Relative
|
|
80
|
+
# paths are converted to absolute by prepending the mount path
|
|
81
|
+
# of the controller.
|
|
82
|
+
|
|
83
|
+
def render(*args)
|
|
84
|
+
path = encode_uri(*args)
|
|
85
|
+
debug "Rendering '#{path}'" if $DBG
|
|
86
|
+
|
|
87
|
+
@controller, action, query, params, ext = @context.dispatcher.dispatch(path)
|
|
88
|
+
@context.content_type = @context.format.content_type
|
|
89
|
+
|
|
90
|
+
@context.level += 1
|
|
91
|
+
old_controller = Controller.replace_current(@controller)
|
|
92
|
+
|
|
93
|
+
if self.class == @controller
|
|
94
|
+
self.send(action, params)
|
|
95
|
+
else
|
|
96
|
+
@controller.new(@context).send(action, params)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
Controller.replace_current(old_controller)
|
|
100
|
+
@context.level -= 1
|
|
101
|
+
|
|
102
|
+
rescue RenderExit, ActionExit => e1
|
|
103
|
+
# Just stop rendering.
|
|
104
|
+
|
|
105
|
+
rescue ActionError => e2
|
|
106
|
+
# Client Error family of errors, typically send 4XX
|
|
107
|
+
# status code.
|
|
108
|
+
handle_error(e2, 404)
|
|
109
|
+
error e2.to_s
|
|
110
|
+
|
|
111
|
+
rescue Object => e3
|
|
112
|
+
# Server Error family of errors, typically send 5XX
|
|
113
|
+
# status code.
|
|
114
|
+
# puts "--------", pp_exception(e3)
|
|
115
|
+
|
|
116
|
+
handle_error(e3, 500)
|
|
117
|
+
error "Error while handling '#{path}'"
|
|
118
|
+
error pp_exception(e3)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
private
|
|
122
|
+
RADIUS = 3
|
|
123
|
+
|
|
124
|
+
# Extract the offending source code for a server error.
|
|
125
|
+
|
|
126
|
+
def extract_source_from(error)
|
|
127
|
+
extract = []
|
|
128
|
+
|
|
129
|
+
code = error.backtrace[1]
|
|
130
|
+
md = code.match(%r{:(\d+):in `(.*)'$})
|
|
131
|
+
line_num = md[1].to_i
|
|
132
|
+
|
|
133
|
+
code.split("\n")[(line_num - RADIUS)..(line_num + RADIUS)].each_with_index do |line, idx|
|
|
134
|
+
lidx = line_num - RADIUS + idx
|
|
135
|
+
extract << "#{lidx}: #{line}"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
return extract
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Helper method to exit the current action, typically used
|
|
142
|
+
# to skip the template rendering.
|
|
143
|
+
#
|
|
144
|
+
# === Example
|
|
145
|
+
#
|
|
146
|
+
# def my_action
|
|
147
|
+
# ...
|
|
148
|
+
# exit unless user.admin?
|
|
149
|
+
# end
|
|
150
|
+
|
|
151
|
+
def exit
|
|
152
|
+
raise ActionExit.new
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Flush the IO object (OutputBuffer) if we are in streaming
|
|
156
|
+
# mode.
|
|
157
|
+
|
|
158
|
+
def flush
|
|
159
|
+
@out.flush if @out.is_a?(IO)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# :section: Redirection methods.
|
|
163
|
+
|
|
164
|
+
# Send a redirect response.
|
|
165
|
+
#
|
|
166
|
+
# If the URI (path) starts with '/' it is considered absolute, else
|
|
167
|
+
# the URI is considered relative to the current controller and
|
|
168
|
+
# the controller base is prepended.
|
|
169
|
+
#
|
|
170
|
+
# The parameters are passed to the R operator (encode_uri)
|
|
171
|
+
# to actually build the URI. So the following forms (among
|
|
172
|
+
# others) are allowed:
|
|
173
|
+
#
|
|
174
|
+
# redirect 'home/login'
|
|
175
|
+
# redirect ForaController, :post, :title, 'The title'
|
|
176
|
+
# redirect :welcome
|
|
177
|
+
# redirect article # => article.to_href
|
|
178
|
+
#
|
|
179
|
+
# You can also pass optional hash parameters at the end,
|
|
180
|
+
# for example:
|
|
181
|
+
#
|
|
182
|
+
# redirect :welcome, :status => 307
|
|
183
|
+
#
|
|
184
|
+
# The default redirect status is 303.
|
|
185
|
+
#
|
|
186
|
+
#--
|
|
187
|
+
# TODO: add a check for redirect to self (infinite loop)
|
|
188
|
+
#++
|
|
189
|
+
|
|
190
|
+
def redirect(*args)
|
|
191
|
+
# If this is an ajax and/or rpc request skip the redirect.
|
|
192
|
+
# Allows to write more reusable code.
|
|
193
|
+
|
|
194
|
+
return if request.script?
|
|
195
|
+
|
|
196
|
+
if args.last.is_a? Hash
|
|
197
|
+
status = args.last.fetch(:status, 303)
|
|
198
|
+
else
|
|
199
|
+
status = 303
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
uri = encode_uri(*args)
|
|
203
|
+
|
|
204
|
+
# gmosx, THINK: this may be unnecessary!
|
|
205
|
+
|
|
206
|
+
unless uri =~ /^http/
|
|
207
|
+
uri = "#{@context.host_uri}/#{uri.gsub(/^\//, '')}"
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
@context.status = status
|
|
211
|
+
@out = "<html><a href=\"#{uri}\">#{uri}</a>.</html>\n"
|
|
212
|
+
@context.response_headers['location'] = uri
|
|
213
|
+
|
|
214
|
+
raise RenderExit
|
|
215
|
+
end
|
|
216
|
+
alias_method :redirect_to, :redirect
|
|
217
|
+
|
|
218
|
+
# Redirect to the referer.
|
|
219
|
+
|
|
220
|
+
def redirect_referer(postfix = nil, status = 303)
|
|
221
|
+
redirect "#{@context.referer}#{postfix}", :status => status
|
|
222
|
+
end
|
|
223
|
+
alias_method :redirect_to_referer, :redirect_referer
|
|
224
|
+
alias_method :redirect_referrer, :redirect_referer
|
|
225
|
+
alias_method :redirect_to_referrer, :redirect_referer
|
|
226
|
+
|
|
227
|
+
# Redirect to home.
|
|
228
|
+
|
|
229
|
+
def redirect_home(status = 303)
|
|
230
|
+
redirect "/", :status => status
|
|
231
|
+
end
|
|
232
|
+
alias_method :redirect_to_home, :redirect_home
|
|
233
|
+
|
|
234
|
+
# Handle an error.
|
|
235
|
+
#--
|
|
236
|
+
# gmosx, TODO: add check for infinite loops here.
|
|
237
|
+
#++
|
|
238
|
+
|
|
239
|
+
def handle_error(exception, error_status = 500)
|
|
240
|
+
@context.status = error_status
|
|
241
|
+
@out = ""
|
|
242
|
+
|
|
243
|
+
session[:RENDERING_ERROR] = exception
|
|
244
|
+
|
|
245
|
+
render("/status_#{error_status}")
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# Convenience method to lookup the session.
|
|
249
|
+
|
|
250
|
+
def session
|
|
251
|
+
@context.session
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
# Add some text to the output buffer.
|
|
255
|
+
|
|
256
|
+
def render_text(text)
|
|
257
|
+
@out << text
|
|
258
|
+
end
|
|
259
|
+
alias_method :print, :render_text
|
|
260
|
+
|
|
261
|
+
# Render a template into the output buffer.
|
|
262
|
+
# HACK FIX, will be removed.
|
|
263
|
+
|
|
264
|
+
def render_template(path)
|
|
265
|
+
render(path)
|
|
266
|
+
exit
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require "glue/builder/xml"
|
|
2
|
+
|
|
3
|
+
module Raw
|
|
4
|
+
|
|
5
|
+
module Render
|
|
6
|
+
|
|
7
|
+
# Access the programmatic renderer (builder).
|
|
8
|
+
|
|
9
|
+
def build(&block)
|
|
10
|
+
if block.arity == 1
|
|
11
|
+
yield XmlBuilder.new(@out)
|
|
12
|
+
else
|
|
13
|
+
XmlBuilder.new(@out).instance_eval(&block)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Return a programmatic renderer that targets the
|
|
18
|
+
# output buffer.
|
|
19
|
+
|
|
20
|
+
def builder
|
|
21
|
+
XmlBuilder.new(@out)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|