Class: HttpRouter::Route

Inherits:
Object
  • Object
show all
Defined in:
lib/http_router/route.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(router, path) ⇒ Route

Returns a new instance of Route.



6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/http_router/route.rb', line 6

def initialize(router, path)
  @router = router
  path[0,0] = '/' unless path[0] == ?/
  @path = path
  @original_path = path.dup
  @partially_match = extract_partial_match(path)
  @trailing_slash_ignore = extract_trailing_slash(path)
  @matches_with = {}
  @arbitrary = []
  @conditions =  {}
  @default_values = {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/http_router/route.rb', line 19

def method_missing(method, *args, &block)
  if RequestNode::RequestMethods.include?(method)
    condition(method => args)
  else
    super
  end
end

Instance Attribute Details

#default_valuesObject

Returns the value of attribute default_values.



4
5
6
# File 'lib/http_router/route.rb', line 4

def default_values
  @default_values
end

#destObject (readonly)

Returns the value of attribute dest.



3
4
5
# File 'lib/http_router/route.rb', line 3

def dest
  @dest
end

#matches_withObject (readonly)

Returns the value of attribute matches_with.



3
4
5
# File 'lib/http_router/route.rb', line 3

def matches_with
  @matches_with
end

#partially_matchObject

Returns the value of attribute partially_match.



4
5
6
# File 'lib/http_router/route.rb', line 4

def partially_match
  @partially_match
end

#pathObject (readonly)

Returns the value of attribute path.



3
4
5
# File 'lib/http_router/route.rb', line 3

def path
  @path
end

#pathsObject (readonly)

Returns the value of attribute paths.



3
4
5
# File 'lib/http_router/route.rb', line 3

def paths
  @paths
end

#trailing_slash_ignoreObject

Returns the value of attribute trailing_slash_ignore.



4
5
6
# File 'lib/http_router/route.rb', line 4

def trailing_slash_ignore
  @trailing_slash_ignore
end

Instance Method Details

#arbitrary(proc = nil, &block) ⇒ Object

Adds an arbitrary proc matcher to a Route. Receives either a block, or a proc. The proc will receive a Rack::Request object and must return true for the Route to be matched. Returns self.



174
175
176
177
178
# File 'lib/http_router/route.rb', line 174

def arbitrary(proc = nil, &block)
  guard_compiled
  @arbitrary << (proc || block)
  self
end

#as_optionsObject

Returns the options used to create this route.



28
29
30
# File 'lib/http_router/route.rb', line 28

def as_options
  {:matching => @matches_with, :conditions => @conditions, :default_values => @default_values, :name => @name, :partial => @partially_match, :arbitrary => @arbitrary}
end

#clone(new_router) ⇒ Object

Creates a deep uncompiled copy of this route.



33
34
35
# File 'lib/http_router/route.rb', line 33

def clone(new_router)
  Route.new(new_router, @original_path.dup).with_options(as_options)
end

#compileObject

Compiles the route and inserts it into the tree. This is called automatically when you add a destination via #to to the route. Until a route is compiled, it will not be recognized.



187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/http_router/route.rb', line 187

def compile
  if @paths.nil?
    router.named_routes[@name] = self if @name
    @paths = compile_paths
    @paths.each_with_index do |p1, i|
      @paths[i+1, @paths.size].each do |p2|
        raise AmbiguousRouteException.new if p1 === p2
      end
    end
    @paths.each do |path|
      current_node = router.root.add_path(path)
      working_set = current_node.add_request_methods(@conditions)
      working_set.map!{|node| node.add_arbitrary(@arbitrary)}
      working_set.each do |current_node|
        current_node.value = path
      end
    end
  end
  self
end

#compiled?Boolean

Compile state for route. Returns true or false.

Returns:

  • (Boolean)


181
182
183
# File 'lib/http_router/route.rb', line 181

def compiled?
  !@paths.nil?
end

#condition(conditions) ⇒ Object Also known as: conditions

Sets a request condition for the route Returns self.

Example

router = HttpRouter.new
router.add("/:test").condition(:host => 'www.example.org').name(:test).compile


109
110
111
112
113
114
115
116
117
118
# File 'lib/http_router/route.rb', line 109

def condition(conditions)
  guard_compiled
  conditions.each do |k,v|
    @conditions.key?(k) ?
      @conditions[k] << v :
      @conditions[k] = Array(v)
    @conditions[k].flatten!
  end
  self
end

#default(v) ⇒ Object

Sets a default value for the route Returns self.

Example

router = HttpRouter.new
router.add("/:test").default(:test => 'foo').name(:test).compile
router.url(:test)
# ==> "/foo"
router.url(:test, 'override')
# ==> "/override"


73
74
75
76
# File 'lib/http_router/route.rb', line 73

def default(v)
  @default_values.merge!(v)
  self
end

#deleteObject

Causes this route to recognize the DELETE request method. Returns self.



99
100
101
# File 'lib/http_router/route.rb', line 99

def delete
  request_method('DELETE')
end

#getObject

Causes this route to recognize the GET request method. Returns self.



79
80
81
# File 'lib/http_router/route.rb', line 79

def get
  request_method('GET')
end

#headObject

Causes this route to recognize the HEAD request method. Returns self.



89
90
91
# File 'lib/http_router/route.rb', line 89

def head
  request_method('HEAD')
end

#match_path(matcher) ⇒ Object

Convenient regexp matching on an entire path. Returns self



169
170
171
# File 'lib/http_router/route.rb', line 169

def match_path(matcher)
  arbitrary{|env| match = matcher.match(env.path_info); !match.nil? and match.begin(0) == 0 and match[0].size == env.path_info.size}
end

#matching(match) ⇒ Object

Sets a regex matcher for a variable Returns self.

Example

router = HttpRouter.new
router.add("/:test").matching(:test => /\d+/).name(:test).compile


127
128
129
130
131
132
133
134
135
136
# File 'lib/http_router/route.rb', line 127

def matching(match)
  guard_compiled
  match.each do |var_name, matchers|
    matchers = Array(matchers)
    matchers.each do |m|
      @matches_with.key?(var_name) ? raise : @matches_with[var_name] = m
    end
  end
  self
end

#name(name) ⇒ Object

Sets the name of the route Returns self.



57
58
59
60
61
# File 'lib/http_router/route.rb', line 57

def name(name)
  @name = name
  router.named_routes[@name] = self if @name && compiled?
  self
end

#namedObject

Returns the current route’s name.



139
140
141
# File 'lib/http_router/route.rb', line 139

def named
  @name
end

#partial(match = true) ⇒ Object

Sets partial matching on this route. Defaults to true. Returns self.



163
164
165
166
# File 'lib/http_router/route.rb', line 163

def partial(match = true)
  @partially_match = match
  self
end

#partially_match?Boolean

The current state of partial matching on this route. Returns true or false.

Returns:

  • (Boolean)


236
237
238
# File 'lib/http_router/route.rb', line 236

def partially_match?
  @partially_match
end

#postObject

Causes this route to recognize the POST request method. Returns self.



84
85
86
# File 'lib/http_router/route.rb', line 84

def post
  request_method('POST')
end

#putObject

Causes this route to recognize the PUT request method. Returns self.



94
95
96
# File 'lib/http_router/route.rb', line 94

def put
  request_method('PUT')
end

#redirect(path, status = 302) ⇒ Object

Sets the destination of this route to redirect to an arbitrary URL.

Raises:

  • (ArgumentError)


209
210
211
212
213
214
215
216
217
218
# File 'lib/http_router/route.rb', line 209

def redirect(path, status = 302)
  raise(ArgumentError, "Status has to be an integer between 300 and 399") unless (300..399).include?(status)
  to { |env|
    params = env['router.params']
    response = ::Rack::Response.new
    response.redirect(eval(%|"#{path}"|), status)
    response.finish
  }
  self
end

#static(root) ⇒ Object

Sets the destination of this route to serve static files from either a directory or a single file.



221
222
223
224
225
226
227
228
# File 'lib/http_router/route.rb', line 221

def static(root)
  if File.directory?(root)
    partial.to ::Rack::File.new(root)
  else
    to proc{|env| env['PATH_INFO'] = File.basename(root); ::Rack::File.new(File.dirname(root)).call(env)}
  end
  self
end

#to(dest = nil, &block) ⇒ Object

Sets the destination of the route. Receives either a block, or a proc. Returns self.

Example

router = HttpRouter.new
router.add("/:test").matching(:test => /\d+/).name(:test).to(proc{ |env| Rack::Response.new("hi there").finish })

Or

router.add("/:test").matching(:test => /\d+/).name(:test).to { |env| Rack::Response.new("hi there").finish }


151
152
153
154
155
156
157
158
159
160
# File 'lib/http_router/route.rb', line 151

def to(dest = nil, &block)
  compile
  @dest = dest || block
  if @dest.respond_to?(:url_mount=)
    urlmount = UrlMount.new(@original_path, @default_values)
    urlmount.url_mount = router.url_mount if router.url_mount
    @dest.url_mount = urlmount
  end
  self
end

#trailing_slash_ignore?Boolean

The current state of trailing / ignoring on this route. Returns true or false.

Returns:

  • (Boolean)


231
232
233
# File 'lib/http_router/route.rb', line 231

def trailing_slash_ignore?
  @trailing_slash_ignore
end

#url(*args) ⇒ Object

Generates a URL for this route. See HttpRouter#url for how the arguments for this are structured.



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/http_router/route.rb', line 241

def url(*args)
  options = args.last.is_a?(Hash) ? args.pop : nil
  options ||= {} if default_values
  options = default_values.merge(options) if default_values && options
  path = if args.empty?
    matching_path(options)
  else
    matching_path(args, options)
  end
  raise UngeneratableRouteException.new unless path

  mount_point = nil
  if !router.url_mount.nil?
    mount_point = router.url_mount.url(options)
  end

  result = path.url(args, options)
  mount_point.nil? ? result : File.join(mount_point, result)
end

#with_options(options) ⇒ Object

Uses an option hash to apply conditions to a Route. The following keys are supported. *name – Maps to #name method. *matching – Maps to #matching method. *conditions – Maps to #conditions method. *default_value – Maps to #default_value method.



43
44
45
46
47
48
49
50
51
52
53
# File 'lib/http_router/route.rb', line 43

def with_options(options)
  if options
    name(options[:name])                               if options[:name]
    matching(options[:matching])                       if options[:matching]
    condition(options[:conditions])                    if options[:conditions]
    default(options[:default_values])                  if options[:default_values]
    partial(options[:partial])                         if options[:partial]
    Array(options[:arbitrary]).each{|a| arbitrary(&a)} if options[:arbitrary]
  end
  self
end