Module: Raw::Render
- Defined in:
- lib/raw/render.rb,
lib/raw/render/call.rb,
lib/raw/render/stream.rb,
lib/raw/render/builder.rb,
lib/raw/render/send_file.rb
Overview
– Seaside style call/answer methods. ++
Instance Attribute Summary collapse
-
#action_name ⇒ Object
The name of the currently executing action.
-
#context ⇒ Object
(also: #request, #response)
The context.
-
#controller ⇒ Object
The current controller class.
-
#out ⇒ Object
(also: #body)
The output buffer.
Instance Method Summary collapse
-
#answer(force = false, status = 303) ⇒ Object
Returns from a call by poping the callstack.
-
#build(&block) ⇒ Object
Access the programmatic renderer (builder).
-
#builder ⇒ Object
Return a programmatic renderer that targets the output buffer.
-
#call(*args) ⇒ Object
Call redirects to the given URI but push the original URI in a callstack, so that the target can return by executing answer.
-
#initialize(context) ⇒ Object
Initialize the render.
-
#render(*args) ⇒ Object
Renders the action denoted by path.
-
#send_file(fname = nil, fullpath = false) ⇒ Object
(also: #sendfile)
Send a file download to the client.
-
#stream(io = nil) ⇒ Object
Enable streaming mode for the current HTTP Response.
Instance Attribute Details
#action_name ⇒ Object
The name of the currently executing action.
59 60 61 |
# File 'lib/raw/render.rb', line 59 def action_name @action_name end |
#context ⇒ Object Also known as: request, response
The context.
53 54 55 |
# File 'lib/raw/render.rb', line 53 def context @context end |
#controller ⇒ Object
The current controller class.
63 64 65 |
# File 'lib/raw/render.rb', line 63 def controller @controller end |
#out ⇒ Object Also known as: body
The output buffer. The output of a script/action is accumulated in this buffer.
48 49 50 |
# File 'lib/raw/render.rb', line 48 def out @out end |
Instance Method Details
#answer(force = false, status = 303) ⇒ Object
Returns from a call by poping the callstack. Use force = false to make this mechanism more flexible. – FIXME: don’t use yet. ++
29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/raw/render/call.rb', line 29 def answer(force = false, status = 303) if stack = session[:CALL_STACK] and not stack.empty? redirect(stack.pop, :status => status) else if force raise 'Cannot answer, call stack is empty' else redirect_to_home end end end |
#build(&block) ⇒ Object
Access the programmatic renderer (builder).
9 10 11 12 13 14 15 |
# File 'lib/raw/render/builder.rb', line 9 def build(&block) if block.arity == 1 yield XmlBuilder.new(@out) else XmlBuilder.new(@out).instance_eval(&block) end end |
#builder ⇒ Object
Return a programmatic renderer that targets the output buffer.
20 21 22 |
# File 'lib/raw/render/builder.rb', line 20 def builder XmlBuilder.new(@out) end |
#call(*args) ⇒ Object
Call redirects to the given URI but push the original URI in a callstack, so that the target can return by executing answer.
– FIXME: dont use yet, you have to encode the branch to make this safe for use. ++
18 19 20 21 |
# File 'lib/raw/render/call.rb', line 18 def call(*args) (session[:CALL_STACK] ||= []).push(request.uri) redirect(*args) end |
#initialize(context) ⇒ Object
Initialize the render.
context
-
A parent render/controller acts as the context.
70 71 72 73 |
# File 'lib/raw/render.rb', line 70 def initialize(context) @context = context @out = context.output_buffer end |
#render(*args) ⇒ Object
Renders the action denoted by path. The path is resolved by the dispatcher to get the correct controller.
Both relative and absolute paths are supported. Relative paths are converted to absolute by prepending the mount path of the controller.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/raw/render.rb', line 83 def render(*args) path = encode_uri(*args) debug "Rendering '#{path}'" if $DBG @controller, action, query, params, ext = @context.dispatcher.dispatch(path) @context.content_type = @context.format.content_type @context.level += 1 old_controller = Controller.replace_current(@controller) if self.class == @controller self.send(action, params) else @controller.new(@context).send(action, params) end Controller.replace_current(old_controller) @context.level -= 1 rescue RenderExit, ActionExit => e1 # Just stop rendering. rescue ActionError => e2 # Client Error family of errors, typically send 4XX # status code. handle_error(e2, 404) error e2.to_s rescue Object => e3 # Server Error family of errors, typically send 5XX # status code. # puts "--------", pp_exception(e3) handle_error(e3, 500) error "Error while handling '#{path}'" error pp_exception(e3) end |
#send_file(fname = nil, fullpath = false) ⇒ Object Also known as: sendfile
Send a file download to the client.
Like render and redirect, the action is exited upon calling
fname
-
That name of the file
path
-
Specifying true mean fname contains the full path.
The default, false, uses Server.public_root as the path.
return
-
true on success, false on failure
Examples
require “raw/render/send_file”
class MyController < Nitro:Controller
def download(fname)
send_file(fname)
end
end
class MyController < Nitro:Controller
def download
send_file("/etc/password", true)
end
end
33 34 35 36 37 38 39 40 41 |
# File 'lib/raw/render/send_file.rb', line 33 def send_file(fname = nil, fullpath = false) fname = fullpath ? fname : "#{@context.application.public_dir}/#{fname}" f = File.open(fname, "rb") @context.response_headers["Cache-control"] = "private" @context.response_headers["Content-Length"] = "#{File.size?(f) || 0}" @context.response_headers["Content-Type"] = "application/force-download" @context.output_buffer = f raise RenderExit end |
#stream(io = nil) ⇒ Object
Enable streaming mode for the current HTTP Response. You can optionally provide an existing IO object for streaming. – This code is considered a hack fix. But it still is useful so for the moment it stays in the distribution. ++
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/raw/render/stream.rb', line 15 def stream(io = nil) if io # Reuse an existing IO if it exists. @context.output_buffer = io else r, w = IO.pipe @context.output_buffer = r @out = w r.sync = true w.class.send(:define_method, :empty?) { false } Thread.new do begin yield ensure w.close end end end end |