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 collapse
- ENV_ERROR_CONTENT_TYPE =
- 'closure.error.content_type'
Instance Attribute Summary collapse
- 
  
    
      #goog  ⇒ Goog 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    All the cool stuff lives here. 
- 
  
    
      #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. 
- 
  
    
      #expand_src(filename, dir = nil)  ⇒ String 
    
    
  
  
  
  
  
  
  
  
  
    Helper to locate a file as a file server path. 
- 
  
    
      #initialize(env, sources, filename)  ⇒ Script 
    
    
  
  
  
    constructor
  
  
  
  
  
  
  
    A new instance of Script. 
- 
  
    
      #relative_src(filename, dir = nil)  ⇒ String 
    
    
  
  
  
  
  
  
  
  
  
    Helper to locate a file as a file server path. 
- 
  
    
      #render(filename, locals = {})  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    Render another Script. 
Constructor Details
#initialize(env, sources, filename) ⇒ Script
Returns 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 | 
#render_stack ⇒ <Array> (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 | 
#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.
| 61 62 63 | # File 'lib/closure/script.rb', line 61 def response @response end | 
Instance Method Details
#expand_path(filename, dir = nil) ⇒ String
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 | 
#expand_src(filename, dir = nil) ⇒ String
Helper to locate a file as a file server path.
| 135 136 137 138 139 140 141 142 143 144 145 146 147 | # File 'lib/closure/script.rb', line 135 def (filename, dir=nil) filename = filename, dir src = nil @goog.each do |directory, path| dir_range = (directory.length..-1) if filename.index(directory) == 0 src = "#{path}#{filename.slice(dir_range)}" break end end raise Errno::ENOENT unless src src end | 
#relative_src(filename, dir = nil) ⇒ String
Helper to locate a file as a file server path.
| 152 153 154 155 156 | # File 'lib/closure/script.rb', line 152 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 = {}) ⇒ Object
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 fext = File.extname(filename) files1 = [filename] files1 << filename + '.html' if fext == '' files1 << filename.sub(/.html$/,'') if fext == '.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 |