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

Instance Method Summary collapse

Instance Attribute Details

#action_nameObject

The name of the currently executing action.



59
60
61
# File 'lib/raw/render.rb', line 59

def action_name
  @action_name
end

#contextObject Also known as: request, response

The context.



53
54
55
# File 'lib/raw/render.rb', line 53

def context
  @context
end

#controllerObject

The current controller class.



63
64
65
# File 'lib/raw/render.rb', line 63

def controller
  @controller
end

#outObject 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

#builderObject

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

Raises:



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