Class: Addressable::Template

### Home Classes Methods

### In Files

- lib/addressable/template.rb

### Parent

Object

### Namespace

- CLASS Addressable::Template::InvalidTemplateOperatorError
- CLASS Addressable::Template::InvalidTemplateValueError
- CLASS Addressable::Template::MatchData
- CLASS Addressable::Template::TemplateOperatorAbortedError

### Methods

- ::new
- #==
- #eql?
- #expand
- #extract
- #inspect
- #keys
- #match
- #partial_expand
- #variable_defaults
- #variables

### Class/Module Index

Quicksearch

- Addressable
- Addressable::IDNA
- Addressable::IDNA::PunycodeBadInput
- Addressable::IDNA::PunycodeBigOutput
- Addressable::IDNA::PunycodeOverflow
- Addressable::Template
- Addressable::Template::InvalidTemplateOperatorError
- Addressable::Template::InvalidTemplateValueError
- Addressable::Template::MatchData
- Addressable::Template::TemplateOperatorAbortedError
- Addressable::VERSION

No matching classes.

# Addressable::Template

This is an implementation of a URI template based on RFC 6570 (tools.ietf.org/html/rfc6570).

### Constants

EXPRESSION
JOINERS
LEADERS
RESERVED
UNRESERVED
VARIABLE_LIST
VARNAME
VARSPEC

### Attributes

pattern[R]

@return [String] The Template object's pattern.

### Public Class Methods

new(pattern) click to toggle source

Creates a new `Addressable::Template` object.

@param [to_str] pattern The URI Template pattern.

@return [Addressable::Template] The initialized Template object.

    # File lib/addressable/template.rb, line 232
    def initialize(pattern)
      if !pattern.respond_to?(:to_str)
        raise TypeError, "Can't convert #{pattern.class} into String."
      end
      @pattern = pattern.to_str.freeze
    end

### Public Instance Methods

==(template) click to toggle source

Returns `true` if the Template objects are equal. This method does NOT normalize either Template before doing the comparison.

@param [Object] template The Template to compare.

@return [TrueClass, FalseClass]

    <code>true</code> if the Templates are equivalent, <code>false</code>
    otherwise.

    # File lib/addressable/template.rb, line 261
    def ==(template)
      return false unless template.kind_of?(Template)
      return self.pattern == template.pattern
    end

Also aliased as: eql?
eql?(template) click to toggle source

Addressable::Template makes no distinction between `==` and `eql?`.

@see #==

Alias for: ==
expand(mapping, processor=nil) click to toggle source

Expands a URI template into a full URI.

@param [Hash] mapping The mapping that corresponds to the pattern. @param [validate, transform] processor

    An optional processor object may be supplied.

The object should respond to either the `validate` or `transform` messages or both. Both the `validate` and `transform` methods should take two parameters: `name` and `value`. The `validate` method should return `true` or `false`; `true` if the value of the variable is valid, `false` otherwise. An `InvalidTemplateValueError` exception will be raised if the value is invalid. The `transform` method should return the transformed variable value as a `String`. If a `transform` method is used, the value will not be percent encoded automatically. Unicode normalization will be performed both before and after sending the value to the transform method.

@return [Addressable::URI] The expanded URI template.

@example

    class ExampleProcessor
      def self.validate(name, value)
        return !!(value =~ /^[\w ]+$/) if name == "query"
        return true
      end

      def self.transform(name, value)
        return value.gsub(/ /, "+") if name == "query"
        return value
      end
    end

    Addressable::Template.new(
      "http://example.com/search/{query}/"
    ).expand(
      {"query" => "an example search query"},
      ExampleProcessor
    ).to_str
    #=> "http://example.com/search/an+example+search+query/"

    Addressable::Template.new(
      "http://example.com/search/{query}/"
    ).expand(
      {"query" => "an example search query"}
    ).to_str
    #=> "http://example.com/search/an%20example%20search%20query/"

    Addressable::Template.new(
      "http://example.com/search/{query}/"
    ).expand(
      {"query" => "bogus!"},
      ExampleProcessor
    ).to_str
    #=> Addressable::Template::InvalidTemplateValueError

    # File lib/addressable/template.rb, line 574
    def expand(mapping, processor=nil)
      result = self.pattern.dup
      mapping = normalize_keys(mapping)
      result.gsub!( EXPRESSION ) do |capture|
        transform_capture(mapping, capture, processor)
      end
      return Addressable::URI.parse(result)
    end

extract(uri, processor=nil) click to toggle source

Extracts a mapping from the URI using a URI Template pattern.

@param [Addressable::URI, to_str] uri

    The URI to extract from.

@param [restore, match] processor

    A template processor object may optionally be supplied.

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

@return [Hash, NilClass]

    The <tt>Hash</tt> mapping that was extracted from the URI, or
    <tt>nil</tt> if the URI didn't match the template.

@example

    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/"
    )
    Addressable::Template.new(
      "http://example.com/search/{query}/"
    ).extract(uri, ExampleProcessor)
    #=> {"query" => "an example search query"}

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

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

    # File lib/addressable/template.rb, line 329
    def extract(uri, processor=nil)
      match_data = self.match(uri, processor)
      return (match_data ? match_data.mapping : nil)
    end

inspect() click to toggle source

Returns a `String` representation of the Template object's state.

@return [String] The Template object's state, as a `String`.

    # File lib/addressable/template.rb, line 247
    def inspect
      sprintf("#<%s:%#0x PATTERN:%s>",
        self.class.to_s, self.object_id, self.pattern)
    end

keys() click to toggle source
Alias for: variables
match(uri, processor=nil) click to toggle source

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

@param [Addressable::URI, to_str] uri

    The URI to extract from.

@param [restore, match] processor

    A template processor object may optionally be supplied.

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

@return [Hash, NilClass]

    The <tt>Hash</tt> mapping that was extracted from the URI, or
    <tt>nil</tt> if the URI didn't match the template.

@example

    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}{/second*}/"
    ).match(uri)
    match.variables
    #=> ["first", "second"]
    match.captures
    #=> ["a", ["b", "c"]]

    # File lib/addressable/template.rb, line 400
    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)

      return nil unless uri.to_str.match(expansion_regexp)
      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
        index = 0
        expansions.each do |expansion|
          _, operator, varlist = *expansion.match(EXPRESSION)
          varlist.split(',').each do |varspec|
            _, name, modifier = *varspec.match(VARSPEC)
            mapping[name] ||= nil
            case operator
            when nil, '+', '#', '/', '.'
              unparsed_value = unparsed_values[index]
              name = varspec[VARSPEC, 1]
              value = unparsed_value
              value = value.split(JOINERS[operator]) if value && modifier == '*'
            when ';', '?', '&'
              if modifier == '*'
                if unparsed_values[index]
                  value = unparsed_values[index].split(JOINERS[operator])
                  value = value.inject({}) do |acc, v|
                    key, val = v.split('=')
                    val = "" if val.nil?
                    acc[key] = val
                    acc
                  end
                end
              else
                if (unparsed_values[index])
                  name, value = unparsed_values[index].split('=')
                  value = "" if value.nil?
                end
              end
            end
            if processor != nil && processor.respond_to?(:restore)
              value = processor.restore(name, value)
            end
            if processor == nil
              if value.is_a?(Hash)
                value = value.inject({}){|acc, (k, v)|
                  acc[Addressable::URI.unencode_component(k)] =
                    Addressable::URI.unencode_component(v)
                  acc
                }
              elsif value.is_a?(Array)
                value = value.map{|v| Addressable::URI.unencode_component(v) }
              else
                value = Addressable::URI.unencode_component(value)
              end
            end
            if !mapping.has_key?(name) || mapping[name].nil?
              # Doesn't exist, set to value (even if value is nil)
              mapping[name] = value
            end
            index = index + 1
          end
        end
        return Addressable::Template::MatchData.new(uri, self, mapping)
      else
        return nil
      end
    end

partial_expand(mapping, processor=nil) click to toggle source

Expands a URI template into another URI template.

@param [Hash] mapping The mapping that corresponds to the pattern. @param [validate, transform] processor

    An optional processor object may be supplied.

The object should respond to either the `validate` or `transform` messages or both. Both the `validate` and `transform` methods should take two parameters: `name` and `value`. The `validate` method should return `true` or `false`; `true` if the value of the variable is valid, `false` otherwise. An `InvalidTemplateValueError` exception will be raised if the value is invalid. The `transform` method should return the transformed variable value as a `String`. If a `transform` method is used, the value will not be percent encoded automatically. Unicode normalization will be performed both before and after sending the value to the transform method.

@return [Addressable::Template] The partially expanded URI template.

@example

    Addressable::Template.new(
      "http://example.com/{one}/{two}/"
    ).partial_expand({"one" => "1"}).pattern
    #=> "http://example.com/1/{two}/"

    Addressable::Template.new(
      "http://example.com/{?one,two}/"
    ).partial_expand({"one" => "1"}).pattern
    #=> "http://example.com/?one=1{&two}/"

    Addressable::Template.new(
      "http://example.com/{?one,two,three}/"
    ).partial_expand({"one" => "1", "three" => 3}).pattern
    #=> "http://example.com/?one=1{&two}&three=3"

    # File lib/addressable/template.rb, line 509
    def partial_expand(mapping, processor=nil)
      result = self.pattern.dup
      mapping = normalize_keys(mapping)
      result.gsub!( EXPRESSION ) do |capture|
        transform_partial_capture(mapping, capture, processor)
      end
      return Addressable::Template.new(result)
    end

variable_defaults() click to toggle source

Returns a mapping of variables to their default values specified in the template. Variables without defaults are not returned.

@return [Hash] Mapping of template variables to their defaults

    # File lib/addressable/template.rb, line 600
    def variable_defaults
      @variable_defaults ||=
        Hash[*ordered_variable_defaults.reject { |k, v| v.nil? }.flatten]
    end

variables() click to toggle source

Returns an Array of variables used within the template pattern. The variables are listed in the Array in the order they appear within the pattern. Multiple occurrences of a variable within a pattern are not represented in this Array.

@return [Array] The variables present in the template's pattern.

    # File lib/addressable/template.rb, line 590
    def variables
      @variables ||= ordered_variable_defaults.map { |var, val| var }.uniq
    end

Also aliased as: keys

[Validate]

Generated with the Darkfish Rdoc Generator 2.