Class: Addressable::Template
- Inherits:
-
Object
- Object
- Addressable::Template
- Defined in:
- lib/addressable/template.rb
Overview
This is an implementation of a URI template based on <a href=“tinyurl.com/uritemplatedraft03”>URI Template draft 03</a>.
Defined Under Namespace
Classes: InvalidTemplateOperatorError, InvalidTemplateValueError, MatchData, TemplateOperatorAbortedError
Constant Summary collapse
- OPERATOR_EXPANSION =
/\{-([a-zA-Z]+)\|([#{anything}]+)\|([#{anything}]+)\}/
- VARIABLE_EXPANSION =
/\{([#{anything}]+?)(?:=([#{anything}]+))?\}/
Instance Attribute Summary collapse
-
#pattern ⇒ String
readonly
The Template object’s pattern.
Instance Method Summary collapse
-
#expand(mapping, processor = nil) ⇒ Addressable::URI
Expands a URI template into a full URI.
-
#extract(uri, processor = nil) ⇒ Hash, NilClass
Extracts a mapping from the URI using a URI Template pattern.
-
#initialize(pattern) ⇒ Addressable::Template
constructor
Creates a new
Addressable::Template
object. -
#inspect ⇒ String
Returns a
String
representation of the Template object’s state. -
#match(uri, processor = nil) ⇒ Hash, NilClass
Extracts match data from the URI using a URI Template pattern.
-
#partial_expand(mapping, processor = nil) ⇒ Addressable::Template
Expands a URI template into another URI template.
-
#variable_defaults ⇒ Hash
Returns a mapping of variables to their default values specified in the template.
-
#variables ⇒ Array
(also: #keys)
Returns an Array of variables used within the template pattern.
Constructor Details
#initialize(pattern) ⇒ Addressable::Template
Creates a new Addressable::Template
object.
129 130 131 132 133 134 |
# File 'lib/addressable/template.rb', line 129 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 |
Instance Attribute Details
#pattern ⇒ String (readonly)
Returns The Template object’s pattern.
138 139 140 |
# File 'lib/addressable/template.rb', line 138 def pattern @pattern end |
Instance Method Details
#expand(mapping, processor = nil) ⇒ Addressable::URI
Expands a URI template into a full URI.
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.
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 |
# File 'lib/addressable/template.rb', line 456 def (mapping, processor=nil) result = self.pattern.dup transformed_mapping = transform_mapping(mapping, processor) result.gsub!( /#{OPERATOR_EXPANSION}|#{VARIABLE_EXPANSION}/ ) do |capture| if capture =~ OPERATOR_EXPANSION operator, argument, variables, default_mapping = parse_template_expansion(capture, transformed_mapping) = "expand_#{operator}_operator" if ([, .to_sym] & private_methods).empty? raise InvalidTemplateOperatorError, "Invalid template operator: #{operator}" else send(.to_sym, argument, variables, default_mapping) end else varname, _, vardefault = capture.scan(/^\{(.+?)(=(.*))?\}$/)[0] transformed_mapping[varname] || vardefault end end return Addressable::URI.parse(result) end |
#extract(uri, processor = nil) ⇒ Hash, NilClass
Extracts a mapping 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.
204 205 206 207 |
# File 'lib/addressable/template.rb', line 204 def extract(uri, processor=nil) match_data = self.match(uri, processor) return (match_data ? match_data.mapping : nil) end |
#inspect ⇒ String
Returns a String
representation of the Template object’s state.
144 145 146 147 |
# File 'lib/addressable/template.rb', line 144 def inspect sprintf("#<%s:%#0x PATTERN:%s>", self.class.to_s, self.object_id, self.pattern) end |
#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.
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 |
#partial_expand(mapping, processor = nil) ⇒ Addressable::Template
Expands a URI template into another URI template.
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.
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 |
# File 'lib/addressable/template.rb', line 367 def (mapping, processor=nil) result = self.pattern.dup transformed_mapping = transform_mapping(mapping, processor) result.gsub!( /#{OPERATOR_EXPANSION}|#{VARIABLE_EXPANSION}/ ) do |capture| if capture =~ OPERATOR_EXPANSION operator, argument, variables, default_mapping = parse_template_expansion(capture, transformed_mapping) = "expand_#{operator}_operator" if ([, .to_sym] & private_methods).empty? raise InvalidTemplateOperatorError, "Invalid template operator: #{operator}" else send( .to_sym, argument, variables, default_mapping, true ) end else varname, _, vardefault = capture.scan(/^\{(.+?)(=(.*))?\}$/)[0] if transformed_mapping[varname] transformed_mapping[varname] elsif vardefault "{#{varname}=#{vardefault}}" else "{#{varname}}" end end end return Addressable::Template.new(result) end |
#variable_defaults ⇒ Hash
Returns a mapping of variables to their default values specified in the template. Variables without defaults are not returned.
497 498 499 500 |
# File 'lib/addressable/template.rb', line 497 def variable_defaults @variable_defaults ||= Hash[*ordered_variable_defaults.reject { |k, v| v.nil? }.flatten] end |
#variables ⇒ Array Also known as: keys
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.
487 488 489 |
# File 'lib/addressable/template.rb', line 487 def variables @variables ||= ordered_variable_defaults.map { |var, val| var }.uniq end |