Class: Whisper::Handler
- Inherits:
-
Object
- Object
- Whisper::Handler
- Includes:
- Loggy
- Defined in:
- lib/whisper/handler.rb
Overview
I borrowed a bit from Rails’s syntax, but the semantics are not the same. Anything with + signs will be treated as a substitutable path component. You can optionally end the path spec with :format or /:page:format.
Constant Summary collapse
- DEFAULT_FORMAT =
"html"
Instance Method Summary collapse
- #contents ⇒ Object
- #handle(path, params, request_method, route) ⇒ Object
-
#initialize(request_method, pathspec, &page_creator) ⇒ Handler
constructor
A new instance of Handler.
- #url_for(opts = {}) ⇒ Object
Constructor Details
#initialize(request_method, pathspec, &page_creator) ⇒ Handler
Returns a new instance of Handler.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/whisper/handler.rb', line 17 def initialize request_method, pathspec, &page_creator @request_method = request_method @pathspec = pathspec @page_creator = page_creator @map = TimedMap.new @uses_page = @uses_format = false re = @pathspec.gsub(/\+(\w+)/) do '([^\.\/][^\/]*?)' # regular path components must start with a non-., non-/, followed by 0 or more non-/es end.sub(/\/:page:format$/) do @uses_page = @uses_format = true '\/?(\d+)?(?:\.([^\/]+))?' end.sub(/:format$/) do @uses_format = true '(?:\.([a-zA-Z]+))?' end @re = /^#{re}$/ end |
Instance Method Details
#contents ⇒ Object
68 |
# File 'lib/whisper/handler.rb', line 68 def contents; @map.values end |
#handle(path, params, request_method, route) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/whisper/handler.rb', line 36 def handle path, params, request_method, route #debug "comparing #{request_method.inspect} against #{@request_method.inspect}" return unless (request_method == @request_method) || # special case: (request_method == :head && @request_method == :get) # proceed! #debug "comparing #{path.inspect} against #{@re} => #{@re.match(path) ? true : false}" match = @re.match(path) or return #debug "have captures: #{match.captures.inspect}" ## assemble the variables to be passed to the caller function vars = match.captures vars[vars.length - 1] ||= DEFAULT_FORMAT if @uses_format vars[vars.length - 2] = (vars[vars.length - 2].to_i || 0) if @uses_page vars << params ## make a key from the path and the query parameters, if any. the key is basically ## a normalized query string. key = path + "?" + params.sort_by { |k, v| [k, v] }.map { |k, v| k + "=" + v }.join("&") case request_method when :post # don't cache make route, vars else @map.prune! @map[key] ||= begin make(route, vars) || :invalid rescue SystemCallError => e :invalid end end end |
#url_for(opts = {}) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/whisper/handler.rb', line 70 def url_for opts={} url = @pathspec.gsub(/[:+](\w+)/) do spec = $1.intern val = opts[spec] val = CGI.escape(val.to_s) if val case spec when :format; val.nil? || (val == DEFAULT_FORMAT) ? "" : ".#{val}" when :page; val == "0" ? "" : val else raise ArgumentError, "missing required path spec #{spec}" unless val val end end url += "##{opts[:anchor]}" if opts[:anchor] url.gsub!(/\/\.([^\/\.]+)$/, ".\\1") url end |