* Only add :format to routes if otherwise not explicitly set.
[sinatra.git] / lib / sinatra / route.rb
blob7e0007f55ccf672d5d5e302b788738f12524109f
1 module Sinatra
3   class Route
5     SYMBOL_FIND = /:[a-z_]+/.freeze
6     PARENTHETICAL_SEGMENT_STRING = "([^\/.,;?]+)".freeze
8     attr_reader :regex, :params
10     def initialize(template)
11       @template = template.to_s.strip
12       @default_params = { :format => 'html' }
13       @params = {}
14       extract_keys
15       genereate_route
16     end
17   
18     def recognize(path)
19       @params.clear
20       
21       param_values = path.match(@regex).captures.compact rescue nil
22             
23       if param_values
24         keys = @keys.size < param_values.size ? @keys.concat([:format]) : @keys
25         @params = @default_params.merge(@keys.zip(param_values).to_hash)
26         true
27       else
28         false
29       end
30     end
32     private
33     
34       def extract_keys
35         @keys = @template.scan(SYMBOL_FIND).map { |raw| eval(raw) }
36         @keys
37       end
39       def genereate_route_without_format
40         template = @template.dup
41         template.gsub!(/\.:format$/, '')
42         to_regex_route(template)
43       end
45       def genereate_route_with_format
46         template = @template.dup
47         if template =~ /\.:format$|\.([\w\d]+)$/
48           @default_params[:format] = $1 if $1
49         else
50           template << '.:format'
51         end
52         to_regex_route(template)
53       end
54   
55       def to_regex_route(template)
56         /^#{template.gsub(/\./, '\.').gsub(SYMBOL_FIND, PARENTHETICAL_SEGMENT_STRING)}$/
57       end
59       def genereate_route
60         @regex = Regexp.union(genereate_route_without_format, genereate_route_with_format)
61       end
63   end
65 end