Class: Exocora::Sheet
- Inherits:
-
Object
- Object
- Exocora::Sheet
- Defined in:
- lib/exocora/sheet.rb
Overview
A single CGI script. Requests are processed through a chain of actions
validate - extract and sanitize data from the CGI request process - do stuff render - render to the specified template.
Constant Summary collapse
- @@validations =
Parameters with validations
Hash.new
Instance Attribute Summary collapse
-
#errors ⇒ Object
readonly
Returns the value of attribute errors.
-
#params ⇒ Object
readonly
Returns the value of attribute params.
Class Method Summary collapse
-
.add_validation(param, validation) ⇒ Object
Add a validation to the validation stack.
-
.run ⇒ Object
Creates an instance of this sheet, and runs it.
-
.validate(param, message = 'must be valid', &block) ⇒ Object
Adds a validation condition for a parameter.
-
.validate_presence_of(param, *params) ⇒ Object
Ensure that a parameter is non-nil.
Instance Method Summary collapse
-
#add_error(param, error) ⇒ Object
Adds an error on a parameter.
-
#cast_params(params) ⇒ Object
Casts incoming CGI parameters to nil, numerics, collapses single-element arrays, and so forth.
-
#initialize ⇒ Sheet
constructor
A new instance of Sheet.
-
#log(message) ⇒ Object
Logs a message to a file.
-
#log_to(file) ⇒ Object
Chooses the file for logging.
-
#output(string) ⇒ Object
Sends output to the client.
-
#process ⇒ Object
Process is the meat of the script.
-
#redirect_to(uri_fragment = @cgi.uri, params = {}) ⇒ Object
Breaks the normal rendering flow, and outputs an HTTP redirect header.
-
#render(context = Erubis::Context.new) ⇒ Object
Renders the erubis template for this action.
-
#request ⇒ Object
Accessor for the CGI object.
-
#run ⇒ Object
This is the action which initiates processing of the script.
-
#url_for(url = @cgi.uri, params = {}) ⇒ Object
Returns a URL for the given url and parameters.
-
#use_template(template) ⇒ Object
Sets the name of the template to render.
-
#valid?(param = nil) ⇒ Boolean
Returns true if the specified (or all) parameters have no errors.
-
#validate(params = @params) ⇒ Object
Validates CGI parameters according to @@validations.
Constructor Details
Instance Attribute Details
#errors ⇒ Object (readonly)
Returns the value of attribute errors.
11 12 13 |
# File 'lib/exocora/sheet.rb', line 11 def errors @errors end |
#params ⇒ Object (readonly)
Returns the value of attribute params.
11 12 13 |
# File 'lib/exocora/sheet.rb', line 11 def params @params end |
Class Method Details
.add_validation(param, validation) ⇒ Object
Add a validation to the validation stack
26 27 28 29 30 |
# File 'lib/exocora/sheet.rb', line 26 def self.add_validation(param, validation) @@validations[param.to_sym] ||= [] @@validations[param.to_sym] << validation validation end |
.run ⇒ Object
Creates an instance of this sheet, and runs it.
50 51 52 |
# File 'lib/exocora/sheet.rb', line 50 def self.run new.run end |
.validate(param, message = 'must be valid', &block) ⇒ Object
Adds a validation condition for a parameter. validate :query { |q| q.size > 0 } validate :query, “is invalid” { |q|
35 36 37 38 39 40 41 42 |
# File 'lib/exocora/sheet.rb', line 35 def self.validate(param, ='must be valid', &block) validation = Validation.new(nil, ) if block_given? validation.when block end add_validation param, validation end |
.validate_presence_of(param, *params) ⇒ Object
Ensure that a parameter is non-nil
45 46 47 |
# File 'lib/exocora/sheet.rb', line 45 def self.validate_presence_of(param, *params) add_validation param, ValidationOfPresence.new(*params) end |
Instance Method Details
#add_error(param, error) ⇒ Object
Adds an error on a parameter
55 56 57 58 |
# File 'lib/exocora/sheet.rb', line 55 def add_error(param, error) @errors[param] ||= [] @errors[param] << error end |
#cast_params(params) ⇒ Object
Casts incoming CGI parameters to nil, numerics, collapses single-element arrays, and so forth.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/exocora/sheet.rb', line 62 def cast_params(params) cast = {} params.each do |key, values| cast_values = values.map do |value| if value =~ /^\d+$/ value.to_i elsif value =~ /^[\d.]+$/ value.to_f else value end end # I prefer indexing by symbols key = key.to_sym # Store cast values if values.empty? cast[key] = nil elsif values.size == 1 cast[key] = cast_values.first else cast[key] = cast_values end end cast end |
#log(message) ⇒ Object
Logs a message to a file.
92 93 94 95 96 |
# File 'lib/exocora/sheet.rb', line 92 def log() File.open(@log_file, 'a') do |file| file.puts end end |
#log_to(file) ⇒ Object
Chooses the file for logging.
99 100 101 |
# File 'lib/exocora/sheet.rb', line 99 def log_to(file) @log_file = file end |
#output(string) ⇒ Object
Sends output to the client. The first time output is called, it sends an HTTP header first.
105 106 107 108 109 110 111 112 |
# File 'lib/exocora/sheet.rb', line 105 def output(string) unless @headers_sent puts @cgi.header(@headers) @headers_sent = true end puts string end |
#process ⇒ Object
Process is the meat of the script. It returns a hash like => 2, which become instance variables @a = 2 in the template.
117 118 |
# File 'lib/exocora/sheet.rb', line 117 def process end |
#redirect_to(uri_fragment = @cgi.uri, params = {}) ⇒ Object
Breaks the normal rendering flow, and outputs an HTTP redirect header.
121 122 123 124 125 126 |
# File 'lib/exocora/sheet.rb', line 121 def redirect_to(uri_fragment = @cgi.uri, params = {}) @headers['Status'] = '302 Moved' @headers['Location'] = url_for(@cgi.full_uri_for(uri_fragment), params) output exit end |
#render(context = Erubis::Context.new) ⇒ Object
Renders the erubis template for this action. Takes a hash of variables to render. The default template is determined by underscoring this sheet’s class name, but another template can be specified using #template.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/exocora/sheet.rb', line 131 def render(context = Erubis::Context.new) # Read template data template_filename = "#{@template}.rhtml" begin template = File.read(template_filename) rescue Errno::ENOENT raise ScriptError.new("Template #{template_filename} does not exist!") end # Prepare template and variables eruby = Erubis::Eruby.new template # Perform templating begin result = eruby.evaluate context rescue Exception => e if e.backtrace.first =~ /\(erubis\):(\d+)/ = "encountered error processing template #{template_filename} at line #{$1}" else = "encountered error processing template #{template_filename}" end raise TemplateError.new(, e) end # Output result output result end |
#request ⇒ Object
Accessor for the CGI object
160 161 162 |
# File 'lib/exocora/sheet.rb', line 160 def request @cgi end |
#run ⇒ Object
This is the action which initiates processing of the script.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/exocora/sheet.rb', line 165 def run begin # Cast parameters @params = cast_params @cgi.params # Check parameters validate # Run process context = process # Render output render context rescue # Handle errors output "<html><head><title>Exocora Error</title></head><body>" output "<h1>#{$!.class}</h1>" output $!.to_html output "</body></html>" end end |
#url_for(url = @cgi.uri, params = {}) ⇒ Object
Returns a URL for the given url and parameters
190 191 192 193 194 |
# File 'lib/exocora/sheet.rb', line 190 def url_for(url = @cgi.uri, params = {}) url + params.inject('?') do |query_string, pair| query_string << CGI::escape(pair[0].to_s) + '=' + CGI::escape(pair[1].to_s) end end |
#use_template(template) ⇒ Object
Sets the name of the template to render.
197 198 199 |
# File 'lib/exocora/sheet.rb', line 197 def use_template(template) @template = template end |
#valid?(param = nil) ⇒ Boolean
Returns true if the specified (or all) parameters have no errors.
202 203 204 205 206 207 208 |
# File 'lib/exocora/sheet.rb', line 202 def valid?(param = nil) if param.nil? @errors.empty? else @errors[param].nil? or @errors[param].empty? end end |
#validate(params = @params) ⇒ Object
Validates CGI parameters according to @@validations.
Parameters which fail validation have entries recorderd in @errors.
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/exocora/sheet.rb', line 213 def validate(params = @params) @@validations.each do |param, validations| validations.each do |validation| values = params[param] # If there are multiple values, check each one. unless values.kind_of? Array values = [values] end # if validation.kind_of? ValidationOfPresence # # Make sure we perform a validation even if no parameters are # # present. # begin # validation.validate values.first # rescue ValidationError => e # @errors[param] ||= [] # @errors[param] << e # end # end values.each do |value| begin validation.validate(value) rescue ValidationError => e add_error param, e end end end end params end |