module Nitro # A collection of intelligent url encoding methods. module EncodeUrl private # Encode controller, action, params into a valid url. # Automatically respects nice urls and routing. # # Handles parameters either as a hash or as an array. # Use the array method to pass parameters to 'nice' actions. # # Pass Controller, action, and (param_name, param_value) # pairs. # # === Examples # # encode_url ForaController, :post, :title, 'Hello', :body, 'World' # encode_url :post, :title, 'Hello', :body, 'World' # => implies controller == self # encode_url :kick, :oid, 4 # encode_url article # => article.to_href # # Alternatively you can pass options with a hash: # # encode_url :controller => ForaController, :action => :delete, :params => { :title => 'Hello' } # encode_url :action => :delete #-- # FIXME: better implementation? optimize this? # TODO: move elsewhere. #++ def encode_url(*args) f = args.first # A standard url as string, return as is. if f.is_a? String return f end # If the passed param is an object that responds to :to_href # returns the url to this object. if f.respond_to? :to_href return args.first.to_href end if f.is_a? Symbol # no controller passed, try to use self as controller. if self.is_a? Nitro::Controller args.unshift(self.class) else raise 'No controller passed to encode_url' end end # Try to encode using the router. if url = Context.current.dispatcher.encode_route(*args) return url end # No routing rule, manual encoding. controller = args.shift action = args.shift.to_sym if action == :index url = "#{controller.mount_path}" else mount_path = controller.mount_path mount_path = nil if mount_path == '/' url = "#{mount_path}/#{action}" end unless args.empty? if controller.respond_to_action_or_template? action param_count = controller.instance_method(action).arity if param_count != 0 param_count.times do args.shift # name url << "/#{CGI.escape(args.shift.to_s)}" end end end unless args.empty? url << '?' params = [] (args.size / 2).times do params << "#{args.shift}=#{args.shift}" end url << params.join(';') end end return url end alias R encode_url # Just like encode_url, but generates an absolute url instead. def encode_absolute_url(*args) return "#{request.host_url}#{encode_url(*args)}" end alias RA encode_absolute_url end end