Method: Addressable::Template#match

Defined in:
lib/addressable/template.rb

#match(uri, processor = nil) ⇒ Hash, NilClass

Extracts match data from the URI using a URI Template pattern.

The object should respond to either the restore or match messages or both. The restore method should take two parameters: [String] name and [String] value. The restore method should reverse any transformations that have been performed on the value to ensure a valid URI. The match method should take a single parameter: [String] name. The match method should return a String containing a regular expression capture group for matching on that particular variable. The default value is “.*?”. The match method has no effect on multivariate operator expansions.

The Hash mapping that was extracted from the URI, or nil if the URI didn’t match the template.

Examples:

class ExampleProcessor
  def self.restore(name, value)
    return value.gsub(/\+/, " ") if name == "query"
    return value
  end

  def self.match(name)
    return ".*?" if name == "first"
    return ".*"
  end
end

uri = Addressable::URI.parse(
  "http://example.com/search/an+example+search+query/"
)
match = Addressable::Template.new(
  "http://example.com/search/{query}/"
).match(uri, ExampleProcessor)
match.variables
#=> ["query"]
match.captures
#=> ["an example search query"]

uri = Addressable::URI.parse("http://example.com/a/b/c/")
match = Addressable::Template.new(
  "http://example.com/{first}/{second}/"
).match(uri, ExampleProcessor)
match.variables
#=> ["first", "second"]
match.captures
#=> ["a", "b/c"]

uri = Addressable::URI.parse("http://example.com/a/b/c/")
match = Addressable::Template.new(
  "http://example.com/{first}/{-list|/|second}/"
).match(uri)
match.variables
#=> ["first", "second"]
match.captures
#=> ["a", ["b", "c"]]

Parameters:

  • uri (Addressable::URI, #to_str)

    The URI to extract from.

  • processor (#restore, #match) (defaults to: nil)

    A template processor object may optionally be supplied.

Returns:

  • (Hash, NilClass)


273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'lib/addressable/template.rb', line 273

def match(uri, processor=nil)
  uri = Addressable::URI.parse(uri)
  mapping = {}

  # First, we need to process the pattern, and extract the values.
  expansions, expansion_regexp =
    parse_template_pattern(pattern, processor)
  unparsed_values = uri.to_str.scan(expansion_regexp).flatten

  if uri.to_str == pattern
    return Addressable::Template::MatchData.new(uri, self, mapping)
  elsif expansions.size > 0 && expansions.size == unparsed_values.size
    expansions.each_with_index do |expansion, index|
      unparsed_value = unparsed_values[index]
      if expansion =~ OPERATOR_EXPANSION
        operator, argument, variables =
          parse_template_expansion(expansion)
        extract_method = "extract_#{operator}_operator"
        if ([extract_method, extract_method.to_sym] &
            private_methods).empty?
          raise InvalidTemplateOperatorError,
            "Invalid template operator: #{operator}"
        else
          begin
            send(
              extract_method.to_sym, unparsed_value, processor,
              argument, variables, mapping
            )
          rescue TemplateOperatorAbortedError
            return nil
          end
        end
      else
        name = expansion[VARIABLE_EXPANSION, 1]
        value = unparsed_value
        if processor != nil && processor.respond_to?(:restore)
          value = processor.restore(name, value)
        end
        if mapping[name] == nil || mapping[name] == value
          mapping[name] = value
        else
          return nil
        end
      end
    end
    return Addressable::Template::MatchData.new(uri, self, mapping)
  else
    return nil
  end
end