Class: Radio::HTTP::Script
- Inherits:
-
Rack::Request
- Object
- Rack::Request
- Radio::HTTP::Script
- Includes:
- ERB::Util
- Defined in:
- lib/radio/http/script.rb
Overview
A Script instance is the context in which scripts are rendered. It inherits everything from Rack::Request and supplies a Response instance you can use for redirects, cookies, and other controller actions.
Defined Under Namespace
Classes: NotFound, RenderStackOverflow
Instance Attribute Summary collapse
-
#render_stack ⇒ <Array>
readonly
An array of filenames representing the current render stack.
-
#response ⇒ Rack::Response
After rendering, #finish will be sent to the client.
Instance Method Summary collapse
-
#expand_path(filename, dir = nil) ⇒ String
Helper for finding files relative to Scripts.
-
#initialize(env, filename) ⇒ Script
constructor
A new instance of Script.
-
#render(filename, locals = {}) ⇒ Object
Render another Script.
Constructor Details
#initialize(env, filename) ⇒ Script
Returns a new instance of Script.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/radio/http/script.rb', line 35 def initialize(env, filename) super(env) @render_stack = [] @response = original_response = Rack::Response.new rendering = render(filename) if @response == original_response and @response.empty? @response.write rendering end rescue RenderStackOverflow, NotFound => e if @render_stack.size > 0 # Make errors appear from the render instead of the engine.call e.set_backtrace e.backtrace[1..-1] raise e end @response.status = 404 @response.write "404 Not Found\n" @response.header["X-Cascade"] = "pass" @response.header["Content-Type"] = "text/plain" end |
Instance Attribute Details
#render_stack ⇒ <Array> (readonly)
An array of filenames representing the current render stack.
70 71 72 |
# File 'lib/radio/http/script.rb', line 70 def render_stack @render_stack end |
#response ⇒ Rack::Response
After rendering, #finish will be sent to the client. If you replace the response or add to the response#body, the script engine rendering will not be added.
59 60 61 |
# File 'lib/radio/http/script.rb', line 59 def response @response end |
Instance Method Details
#expand_path(filename, dir = nil) ⇒ String
Helper for finding files relative to Scripts.
123 124 125 126 |
# File 'lib/radio/http/script.rb', line 123 def (filename, dir=nil) dir ||= File.dirname render_stack.last File. filename, dir end |
#render(filename, locals = {}) ⇒ Object
Render another Script.
77 78 79 80 81 82 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 |
# File 'lib/radio/http/script.rb', line 77 def render(filename, locals = {}) if render_stack.size > 100 # Since nobody sane should recurse through here, this mainly # finds a render self that you might get after a copy and paste raise RenderStackOverflow elsif render_stack.size > 0 # Hooray for relative paths and easily movable files filename = File.(filename, File.dirname(render_stack.last)) else # Underbar scripts are partials by convention; keep them from rendering at root filename = File.(filename) raise NotFound if File.basename(filename) =~ /^_/ end ext = File.extname(filename) files1 = [filename] files1 << filename + '.html' if ext == '' files1 << filename.sub(/.html$/,'') if ext == '.html' files1.each do |filename1| files2 = [filename1+'.erb'] files2 << filename1.gsub(/.html$/, '.erb') if File.extname(filename1) == '.html' unless filename1 =~ /^_/ or render_stack.empty? files2 = files2 + files2.collect {|f| "#{File.dirname(f)}/_#{File.basename(f)}"} end files2.each do |filename2| if File.file?(filename2) and File.readable?(filename2) if render_stack.empty? response.header["Content-Type"] = Rack::Mime.mime_type(File.extname(filename1), 'text/html') end render_stack.push filename2 erb = ::ERB.new(File.read(filename2), nil, '-') erb.filename = filename2 set_locals = locals.keys.map { |k| "#{k}=locals[#{k.inspect}];" }.join instance_binding = instance_eval{binding} eval set_locals, instance_binding result = erb.result instance_binding render_stack.pop return result end end end raise NotFound end |