Sha256: b6741c8a22c68e5fd9843772452b5af0cd3bcd7842bce96d6218e88911aab284

Contents?: true

Size: 1.87 KB

Versions: 7

Compression:

Stored size: 1.87 KB

Contents

require 'rack'
require 'dragonfly/utils'

module Dragonfly
  class UrlMapper

    # Exceptions
    class BadUrlFormat < StandardError; end

    class Segment < Struct.new(:param, :seperator, :pattern)
      def regexp_string
        @regexp_string ||= "(#{Regexp.escape(seperator)}#{pattern}+?)?"
      end
    end

    def initialize(url_format, patterns={})
      @url_format = url_format
      raise BadUrlFormat, "bad url format #{url_format}" if url_format[/[\w_]:[\w_]/]
      init_segments(patterns)
      init_url_regexp
    end

    attr_reader :url_format, :url_regexp, :segments

    def params_for(path, query=nil)
      if path and md = path.match(url_regexp)
        params = Rack::Utils.parse_query(query)
        params_in_url.each_with_index do |var, i|
          value = md[i+1][1..-1] if md[i+1]
          params[var] = value && Utils.uri_unescape(value)
        end
        params
      end
    end

    def params_in_url
      @params_in_url ||= url_format.scan(/\:[\w_]+/).map{|f| f.tr(':','') }
    end

    def url_for(params)
      params = params.dup
      url = url_format.dup
      segments.each do |seg|
        value = params[seg.param]
        value ? url.sub!(/:[\w_]+/, Utils.uri_escape_segment(value.to_s)) : url.sub!(/.:[\w_]+/, '')
        params.delete(seg.param)
      end
      url << "?#{Rack::Utils.build_query(params)}" if params.any?
      url
    end

    private

    def init_segments(patterns)
      @segments = []
      url_format.scan(/([^\w_]):([\w_]+)/).each do |seperator, param|
        segments << Segment.new(
          param,
          seperator,
          patterns[param.to_sym] || '[^\/\-\.]'
        )
      end
    end

    def init_url_regexp
      i = -1
      regexp_string = url_format.gsub(/[^\w_]:[\w_]+/) do
        i += 1
        segments[i].regexp_string
      end
      @url_regexp = Regexp.new('^' + regexp_string + '$')
    end

  end
end

Version data entries

7 entries across 7 versions & 1 rubygems

Version Path
dragonfly-1.0.6 lib/dragonfly/url_mapper.rb
dragonfly-1.0.5 lib/dragonfly/url_mapper.rb
dragonfly-1.0.4 lib/dragonfly/url_mapper.rb
dragonfly-1.0.3 lib/dragonfly/url_mapper.rb
dragonfly-1.0.2 lib/dragonfly/url_mapper.rb
dragonfly-1.0.1 lib/dragonfly/url_mapper.rb
dragonfly-1.0 lib/dragonfly/url_mapper.rb