Class: Closure::Script
- Inherits:
-
Rack::Request
- Object
- Rack::Request
- Closure::Script
- Defined in:
- lib/closure/script.rb
Overview
A Closure::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
Constant Summary
- ENV_ERROR_CONTENT_TYPE =
'closure.error.content_type'
Instance Attribute Summary (collapse)
-
- (Goog) goog
All the cool stuff lives here.
-
- (<Array>) render_stack
readonly
An array of filenames representing the current render stack.
-
- (Rack::Response) response
After rendering, #finish will be sent to the client.
Instance Method Summary (collapse)
-
- (String) expand_path(filename, dir = nil)
Helper for finding files relative to Scripts.
-
- (String) expand_src(filename, dir = nil)
Helper to locate a file as a file server path.
-
- (Script) initialize(env, sources, filename)
constructor
A new instance of Script.
-
- (String) relative_src(filename, dir = nil)
Helper to locate a file as a file server path.
-
- render(filename, locals = {})
Render another Script.
Constructor Details
- (Script) initialize(env, sources, filename)
A new instance of Script
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/closure/script.rb', line 32 def initialize(env, sources, filename) super(env) @render_stack = [] @goog = Goog.new(env, sources, @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] env[ENV_ERROR_CONTENT_TYPE] = @response.finish[1]["Content-Type"] rescue nil raise e end @response.status = 404 @response.write "404 Not Found\n" @response.header["X-Cascade"] = "pass" @response.header["Content-Type"] = "text/plain" rescue StandardError, LoadError, SyntaxError => e env[ENV_ERROR_CONTENT_TYPE] = @response.finish[1]["Content-Type"] rescue nil raise e end |
Instance Attribute Details
- (Goog) goog
All the cool stuff lives here.
65 66 67 |
# File 'lib/closure/script.rb', line 65 def goog @goog end |
- (<Array>) render_stack (readonly)
An array of filenames representing the current render stack.
76 77 78 |
# File 'lib/closure/script.rb', line 76 def render_stack @render_stack end |
- (Rack::Response) 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.
61 62 63 |
# File 'lib/closure/script.rb', line 61 def response @response end |
Instance Method Details
- (String) expand_path(filename, dir = nil)
Helper for finding files relative to Scripts.
127 128 129 130 |
# File 'lib/closure/script.rb', line 127 def (filename, dir=nil) dir ||= File.dirname render_stack.last File. filename, dir end |
- (String) expand_src(filename, dir = nil)
Helper to locate a file as a file server path.
135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/closure/script.rb', line 135 def (filename, dir=nil) found = false filename = filename, dir src = nil @goog.each do |dir, path| dir_range = (dir.length..-1) if filename.index(dir) == 0 src = "#{path}#{filename.slice(dir_range)}" break end end raise Errno::ENOENT unless src src end |
- (String) relative_src(filename, dir = nil)
Helper to locate a file as a file server path.
153 154 155 156 157 |
# File 'lib/closure/script.rb', line 153 def relative_src(filename, dir=nil) file = filename, dir base = Pathname.new File.dirname path_info Pathname.new(file).relative_path_from(base).to_s end |
- render(filename, locals = {})
Render another Script.
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 120 121 122 |
# File 'lib/closure/script.rb', line 83 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| Closure.config.engines.each do |ext, engine| files2 = [filename1+ext] files2 << filename1.gsub(/.html$/, ext) 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 @goog.add_dependency filename2 result = engine.call self, locals render_stack.pop return result end end end end raise NotFound end |