lib/plezi/handlers/http_router.rb in plezi-0.12.15 vs lib/plezi/handlers/http_router.rb in plezi-0.12.16
- old
+ new
@@ -89,9 +89,64 @@
Iodine.error e
Base::HTTPSender.send_by_code request, response, 500
end
end
+ # This method attempts to guess at the desired controller's URL, based on it's first path in order of route creation (ignoring host hierarchy).
+ #
+ # This will be usually used by the Controller's #url_for method to get the relative part of the url.
+ def url_for controller, dest, params = {}
+ raise TypeError, "Expecting destination parameter to be a Hash" unless dest.is_a?(Hash)
+ host = nil
+ @hosts.values.each do |h|
+ h.routes.each {|r| (host = h) && (controller = r.controller) && break if r.controller && r.controller.ancestors.include?(controller) }
+ break if host
+ end
+ raise "couldn't find Controller's route and host." unless host
+ url = []
+ dest = dest.dup
+ dest.default_proc = Plezi::Base::Helpers::HASH_SYM_PROC
+ host.routes.each do |r|
+ if r.controller == false
+ add = []
+ r.url_array.each do |sec|
+ next if sec == '*'
+ param_name = (::Plezi::Base::Route::REGEXP_OPTIONAL_PARAMS.match(sec) || ::Plezi::Base::Route::REGEXP_FORMATTED_OPTIONAL_PARAMS.match(sec) || ::Plezi::Base::Route::REGEXP_REQUIRED_PARAMS.match(sec) || ::Plezi::Base::Route::REGEXP_FORMATTED_REQUIRED_PARAMS.match(sec))
+ param_name = param_name[1].to_sym if param_name
+
+ if param_name && (dest[param_name] || params[param_name])
+ add << Plezi::Base::Helpers.encode_url(dest.delete(param_name) || params[param_name])
+ elsif !param_name
+ add << sec
+ else
+ add.clear
+ next
+ end
+ end if r.url_array
+ url.concat add
+ end
+ if r.controller == controller
+ raise NotImplementedError, "#url_for isn't implemented for this controller's route - could this be a Regexp based or special route?" unless r.url_array
+ r.url_array.each do |sec|
+ next if sec == '*'
+ param_name = (::Plezi::Base::Route::REGEXP_OPTIONAL_PARAMS.match(sec) || ::Plezi::Base::Route::REGEXP_FORMATTED_OPTIONAL_PARAMS.match(sec) || ::Plezi::Base::Route::REGEXP_REQUIRED_PARAMS.match(sec) || ::Plezi::Base::Route::REGEXP_FORMATTED_REQUIRED_PARAMS.match(sec))
+ param_name = param_name[1].to_sym if param_name
+ if param_name && dest[param_name]
+ url << Plezi::Base::Helpers.encode_url(dest.delete(param_name))
+ elsif !param_name
+ url << sec
+ elsif ::Plezi::Base::Route::REGEXP_REQUIRED_PARAMS === sec || ::Plezi::Base::Route::REGEXP_OPTIONAL_PARAMS === sec
+ url << ''.freeze
+ elsif ::Plezi::Base::Route::REGEXP_FORMATTED_REQUIRED_PARAMS === sec
+ raise ArgumentError, "URL can't be formatted becuse a required parameter (#{param_name.to_s}) isn't specified and it requires a special format (#{::Plezi::Base::Route::REGEXP_FORMATTED_REQUIRED_PARAMS.match(sec)[2]})."
+ end
+ end
+ return "/#{url.join '/'.freeze}#{"?#{dest.map {|k,v| "#{Plezi::Base::Helpers.encode_url k}=#{Plezi::Base::Helpers.encode_url v}" } .join('&'.freeze)}" if dest.any?}"
+ end
+ end
+ false
+ end
+
protected
def get_host host_name
@hosts.each {|k, v| return v if k === host_name}
nil