class Deas::Router

Constants

ALLOW_TRAILING_SLASHES
DEFAULT_REQUEST_TYPE_NAME
InvalidSplatError
REMOVE_TRAILING_SLASHES
RequestType
SLASH
TrailingSlashesError
VALID_TRAILING_SLASHES_VALUES

Attributes

definitions[R]
escape_query_value_proc[R]
request_types[R]
routes[R]
trailing_slashes[R]
urls[R]

Public Class Methods

new(&block) click to toggle source
# File lib/deas/router.rb, line 22
def initialize(&block)
  @request_types = []
  @urls, @routes, @definitions = {}, [], []
  default_request_type_name(DEFAULT_REQUEST_TYPE_NAME)
  escape_query_value{ |v| Rack::Utils.escape(v) }
  self.instance_eval(&block) if !block.nil?
end

Public Instance Methods

add_request_type(name, &proc) click to toggle source
# File lib/deas/router.rb, line 102
def add_request_type(name, &proc)
  @request_types << RequestType.new(name, proc)
end
allow_trailing_slashes() click to toggle source
# File lib/deas/router.rb, line 35
def allow_trailing_slashes
  @trailing_slashes = ALLOW_TRAILING_SLASHES
end
allow_trailing_slashes_set?() click to toggle source
# File lib/deas/router.rb, line 39
def allow_trailing_slashes_set?
  @trailing_slashes == ALLOW_TRAILING_SLASHES
end
apply_definitions!() click to toggle source
# File lib/deas/router.rb, line 132
def apply_definitions!
  self.definitions.each do |(type, args, block)|
    self.send("apply_#{type}", *args, &block)
  end
  self.definitions.clear
  true
end
base_url(value = nil) click to toggle source
# File lib/deas/router.rb, line 60
def base_url(value = nil)
  set_base_url(value) if !value.nil?
  @base_url
end
default_request_type_name(value = nil) click to toggle source
# File lib/deas/router.rb, line 97
def default_request_type_name(value = nil)
  @default_request_type = RequestType.new(value) if !value.nil?
  @default_request_type.name
end
delete(path, *args) click to toggle source
# File lib/deas/router.rb, line 115
def delete(path, *args); self.route(:delete, path, *args); end
escape_query_value(&block) click to toggle source
# File lib/deas/router.rb, line 55
def escape_query_value(&block)
  raise(ArgumentError, "no block given") unless block
  @escape_query_value_proc = block
end
get(path, *args) click to toggle source
# File lib/deas/router.rb, line 111
def get(path, *args);    self.route(:get,    path, *args); end
not_found(from_path, body = nil) click to toggle source
# File lib/deas/router.rb, line 127
def not_found(from_path, body = nil)
  respond_with_args = [404, {}, body || 'Not Found']
  self.definitions.push([:respond_with, [from_path, respond_with_args], nil])
end
patch(path, *args) click to toggle source
# File lib/deas/router.rb, line 114
def patch(path, *args);  self.route(:patch,  path, *args); end
post(path, *args) click to toggle source
# File lib/deas/router.rb, line 112
def post(path, *args);   self.route(:post,   path, *args); end
prepend_base_url(url_path) click to toggle source
# File lib/deas/router.rb, line 69
def prepend_base_url(url_path)
  "#{base_url}#{url_path}"
end
put(path, *args) click to toggle source
# File lib/deas/router.rb, line 113
def put(path, *args);    self.route(:put,    path, *args); end
redirect(from_path, to_path = nil, &block) click to toggle source
# File lib/deas/router.rb, line 122
def redirect(from_path, to_path = nil, &block)
  self.definitions.push([:redirect, [from_path, to_path], block])
  true
end
remove_trailing_slashes() click to toggle source
# File lib/deas/router.rb, line 43
def remove_trailing_slashes
  @trailing_slashes = REMOVE_TRAILING_SLASHES
end
remove_trailing_slashes_set?() click to toggle source
# File lib/deas/router.rb, line 47
def remove_trailing_slashes_set?
  @trailing_slashes == REMOVE_TRAILING_SLASHES
end
request_type_name(request) click to toggle source

ideally someday the request should just know its request type

# File lib/deas/router.rb, line 107
def request_type_name(request)
  (self.request_types.detect{ |rt| rt.proc.call(request) } || @default_request_type).name
end
route(http_method, from_path, *args) click to toggle source
# File lib/deas/router.rb, line 117
def route(http_method, from_path, *args)
  self.definitions.push([:route, [http_method, from_path, *args], nil])
  true
end
set_base_url(value) click to toggle source
# File lib/deas/router.rb, line 65
def set_base_url(value)
  @base_url = value
end
trailing_slashes_set?() click to toggle source
# File lib/deas/router.rb, line 51
def trailing_slashes_set?
  VALID_TRAILING_SLASHES_VALUES.include?(@trailing_slashes)
end
url(name, path, options = nil) click to toggle source
# File lib/deas/router.rb, line 73
def url(name, path, options = nil)
  if !name.kind_of?(::Symbol)
    raise ArgumentError, "invalid name `#{name.inspect}` - "\
                         "named urls must be defined with Symbol names"
  end
  if !path.kind_of?(::String)
    raise ArgumentError, "invalid path `#{path.inspect}` - "\
                         "named urls must be defined with String paths"
  end
  add_url(name, path, options || {})
end
url_for(name, *args) click to toggle source
# File lib/deas/router.rb, line 85
def url_for(name, *args)
  url = self.urls[name.to_sym]
  raise ArgumentError, "no route named `#{name.to_sym.inspect}`" unless url
  begin
    prepend_base_url(url.path_for(*args))
  rescue Deas::Url::NonHashParamsError => err
    raise ArgumentError, "url param values must be passed as a Hash"
  rescue Deas::Url::EmptyNamedValueError => err
    raise ArgumentError, err.message
  end
end
validate!() click to toggle source
# File lib/deas/router.rb, line 156
def validate!
  self.apply_definitions!
  self.routes.each(&:validate!)
  self.validate_trailing_slashes!
  true
end
validate_trailing_slashes!() click to toggle source
# File lib/deas/router.rb, line 140
def validate_trailing_slashes!
  if self.trailing_slashes == REMOVE_TRAILING_SLASHES
    paths = []
    all_missing = self.routes.inject(true) do |result, route|
      paths << route.path if route.path[-1..-1] == SLASH
      result && route.path[-1..-1] != SLASH
    end
    if !all_missing
      msg = "all route paths must *not* end with a \"/\", but these do:\n"\
            "#{paths.join("\n")}"
      raise TrailingSlashesError, msg
    end
  end
  true
end
view_handler_ns(value = nil) click to toggle source
# File lib/deas/router.rb, line 30
def view_handler_ns(value = nil)
  @view_handler_ns = value if !value.nil?
  @view_handler_ns
end

Private Instance Methods

add_route(http_method, path, proxies) click to toggle source
# File lib/deas/router.rb, line 226
def add_route(http_method, path, proxies)
  # splat not at end of path OR
  # at end of path without preceding forward slash
  if path =~ /\*(?!$)|[^\/]\*/
    raise InvalidSplatError, "invalid path `#{path.inspect}` - "\
                             "routes can only have a single splat and " \
                             "it must be the last path segment " \
                             "(ie '/something/*')"
  end
  proxies = HandlerProxies.new(proxies, self.default_request_type_name)
  require 'deas/route'
  Deas::Route.new(http_method, path, proxies).tap{ |r| self.routes.push(r) }
end
add_url(name, path, options) click to toggle source
# File lib/deas/router.rb, line 219
def add_url(name, path, options)
  options[:escape_query_value] ||= self.escape_query_value_proc
  self.urls[name] = Deas::Url.new(name, path, {
    :escape_query_value => options[:escape_query_value]
  })
end
apply_redirect(from_path, to_path = nil, &block) click to toggle source
# File lib/deas/router.rb, line 187
def apply_redirect(from_path, to_path = nil, &block)
  to_url = self.urls[to_path]
  if to_path.kind_of?(::Symbol) && to_url.nil?
    raise ArgumentError, "no url named `#{to_path.inspect}`"
  end
  from_url = self.urls[from_path]
  if from_path.kind_of?(::Symbol) && from_url.nil?
    raise ArgumentError, "no url named `#{from_path.inspect}`"
  end
  from_url_path = from_url.path if from_url

  require 'deas/redirect_proxy'
  proxy = Deas::RedirectProxy.new(self, to_url || to_path, &block)
  proxies = { self.default_request_type_name => proxy }

  add_route(:get, prepend_base_url(from_url_path || from_path), proxies)
end
apply_respond_with(from_path, respond_with_args) click to toggle source
# File lib/deas/router.rb, line 205
def apply_respond_with(from_path, respond_with_args)
  from_url = self.urls[from_path]
  if from_path.kind_of?(::Symbol) && from_url.nil?
    raise ArgumentError, "no url named `#{from_path.inspect}`"
  end
  from_url_path = from_url.path if from_url

  require 'deas/respond_with_proxy'
  proxy = Deas::RespondWithProxy.new(respond_with_args)
  proxies = { self.default_request_type_name => proxy }

  add_route(:get, prepend_base_url(from_url_path || from_path), proxies)
end
apply_route(http_method, from_path, *args) click to toggle source
# File lib/deas/router.rb, line 165
def apply_route(http_method, from_path, *args)
  handler_names        = args.last.kind_of?(::Hash) ? args.pop : {}
  default_handler_name = args.last
  if !handler_names.key?(self.default_request_type_name) && default_handler_name
    handler_names[self.default_request_type_name] = default_handler_name
  end

  from_url = self.urls[from_path]
  if from_path.kind_of?(::Symbol) && from_url.nil?
    raise ArgumentError, "no url named `#{from_path.inspect}`"
  end
  from_url_path = from_url.path if from_url

  require 'deas/route_proxy'
  proxies = handler_names.inject({}) do |proxies, (req_type_name, handler_name)|
    proxies[req_type_name] = Deas::RouteProxy.new(handler_name, self.view_handler_ns)
    proxies
  end

  add_route(http_method, prepend_base_url(from_url_path || from_path), proxies)
end