Module: Padrino::Routing::ClassMethods

Defined in:
padrino-core/lib/padrino-core/application/routing.rb

Overview

Class methods responsible for enhanced routing for controllers.

Instance Method Summary collapse

Instance Method Details

#absolute_url(*args) ⇒ Object

Returns absolute url. By default adds 'localhost' before generated url. To change that `set :base_url, 'example.com'` in your app.



352
353
354
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 352

def absolute_url(*args)
  base_url + url(*args)
end

#add_filter(type, &block) ⇒ Object

Adds a filter hook to a request.



174
175
176
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 174

def add_filter(type, &block)
  filters[type] << block
end

#after(*args, &block) ⇒ Object

Add an after filter hook.

See Also:



167
168
169
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 167

def after(*args, &block)
  add_filter :after, &(args.empty? ? block : construct_filter(*args, &block))
end

#before(*args, &block) ⇒ Object

Add a before filter hook.

See Also:



158
159
160
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 158

def before(*args, &block)
  add_filter :before, &(args.empty? ? block : construct_filter(*args, &block))
end

#compiled_routerObject



274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 274

def compiled_router
  if @deferred_routes
    deferred_routes.each do |routes|
      routes.each do |(route, dest)|
        route.to(&dest)
        route.before_filters.flatten!
        route.after_filters.flatten!
      end
    end
    @deferred_routes = nil
  end
  router
end

#construct_filter(*args, &block) ⇒ Object

Creates a filter to process before/after the matching route.

Examples:

We are be able to filter with String path

before('/') { 'only to :index' }
get(:index} { 'foo' } # => filter match only before this.
get(:main) { 'bar' }

is the same of

before(:index) { 'only to :index' }
get(:index} { 'foo' } # => filter match only before this.
get(:main) { 'bar' }

it works only for the given controller

controller :foo do
  before(:index) { 'only to for :foo_index' }
  get(:index} { 'foo' } # => filter match only before this.
  get(:main) { 'bar' }
end

controller :bar do
  before(:index) { 'only to for :bar_index' }
  get(:index} { 'foo' } # => filter match only before this.
  get(:main) { 'bar' }
end

if filters based on a symbol or regexp

before :index, /main/ do; ... end
# => match only path that are  +/+ or contains +main+

filtering everything except an occurrence

before :except => :index do; ...; end

you can also filter using a request param

before :agent => /IE/ do; ...; end
# => match +HTTP_USER_AGENT+ containing +IE+

Parameters:

  • args (Array)

See Also:



219
220
221
222
223
224
225
226
227
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 219

def construct_filter(*args, &block)
  options = args.last.is_a?(Hash) ? args.pop : {}
  if except = options.delete(:except)
    fail "You cannot use :except with other options specified" unless args.empty? && options.empty?
    except = Array(except)
    options = except.last.is_a?(Hash) ? except.pop : {}
  end
  Filter.new(!except, @_controller, options, Array(except || args), &block)
end

#controller(*args) { ... } ⇒ Object Also known as: controllers

Method to organize our routes in a better way.

In a controller, before and after filters are scoped and don't

affect other controllers or the main app.

In a controller, layouts are scoped and don't affect other

controllers or the main app.

Examples:

controller :admin do
  get :index do; ...; end
  get :show, :with => :id  do; ...; end
end

url(:admin_index) # => "/admin"
url(:admin_show, :id => 1) # "/admin/show/1"

Using named routes follow the sinatra way:

controller "/admin" do
  get "/index" do; ...; end
  get "/show/:id" do; ...; end
end

Supply :provides to all controller routes:

controller :provides => [:html, :xml, :json] do
  get :index do; "respond to html, xml and json"; end
  post :index do; "respond to html, xml and json"; end
  get :foo do; "respond to html, xml and json"; end
end

Specify parent resources in padrino with the :parent option on the controller:

controllers :product, :parent => :user do
  get :index do
    # url is generated as "/user/#{params[:user_id]}/product"
    # url_for(:product, :index, :user_id => 5) => "/user/5/product"
  end
  get :show, :with => :id do
    # url is generated as "/user/#{params[:user_id]}/product/show/#{params[:id]}"
    # url_for(:product, :show, :user_id => 5, :id => 10) => "/user/5/product/show/10"
  end
end

Specify conditions to run for all routes:

controller :conditions => {:protect => true} do
  def self.protect(protected)
    condition do
      halt 403, "No secrets for you!" unless params[:key] == "s3cr3t"
    end if protected
  end

  # This route will only return "secret stuff" if the user goes to
  # `/private?key=s3cr3t`.
  get("/private") { "secret stuff" }

  # And this one, too!
  get("/also-private") { "secret stuff" }

  # But you can override the conditions for each route as needed.
  # This route will be publicly accessible without providing the
  # secret key.
  get :index, :protect => false do
    "Welcome!"
  end
end

Supply default values:

controller :lang => :de do
  get :index, :map => "/:lang" do; "params[:lang] == :de"; end
end
controller :posts do
  layout :post
  before { foo }
  after  { bar }
end

Parameters:

  • args (Array)

    Controller arguments.

Yields:

  • The given block will be used to define the routes within the Controller.



144
145
146
147
148
149
150
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 144

def controller(*args, &block)
  if block_given?
    with_new_options(*args) { instance_eval(&block) }
  else
    include(*args) if extensions.any?
  end
end

#deferred_routesObject



288
289
290
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 288

def deferred_routes
  @deferred_routes ||= ROUTE_PRIORITY.map{[]}
end

#delete(path, *args, &block) ⇒ Object



366
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 366

def delete(path, *args, &block)  route 'DELETE',  path, *args, &block end

#get(path, *args, &block) ⇒ Object



356
357
358
359
360
361
362
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 356

def get(path, *args, &block)
  conditions = @conditions.dup
  route('GET', path, *args, &block)

  @conditions = conditions
  route('HEAD', path, *args, &block)
end

#head(path, *args, &block) ⇒ Object



367
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 367

def head(path, *args, &block)    route 'HEAD',    path, *args, &block end


370
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 370

def link(path, *args, &block)    route 'LINK',    path, *args, &block end

#options(path, *args, &block) ⇒ Object



368
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 368

def options(path, *args, &block) route 'OPTIONS', path, *args, &block end

#parent(name = nil, options = {}) ⇒ Object

Provides many parents with shallowing.

Examples:

controllers :product do
  parent :shop, :optional => true, :map => "/my/stand"
  parent :category, :optional => true
  get :show, :with => :id do
    # generated urls:
    #   "/product/show/#{params[:id]}"
    #   "/my/stand/#{params[:shop_id]}/product/show/#{params[:id]}"
    #   "/my/stand/#{params[:shop_id]}/category/#{params[:category_id]}/product/show/#{params[:id]}"
    # url_for(:product, :show, :id => 10) => "/product/show/10"
    # url_for(:product, :show, :shop_id => 5, :id => 10) => "/my/stand/5/product/show/10"
    # url_for(:product, :show, :shop_id => 5, :category_id => 1, :id => 10) => "/my/stand/5/category/1/product/show/10"
  end
end

Parameters:

  • name (Symbol) (defaults to: nil)

    The parent name.

  • options (Hash) (defaults to: {})

    Additional options.



253
254
255
256
257
258
259
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 253

def parent(name = nil, options={})
  return super() unless name
  defaults = { :optional => false, :map => name.to_s }
  options = defaults.merge(options)
  @_parent = Array(@_parent) unless @_parent.is_a?(Array)
  @_parent << Parent.new(name, options)
end

#patch(path, *args, &block) ⇒ Object



369
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 369

def patch(path, *args, &block)   route 'PATCH',   path, *args, &block end

#post(path, *args, &block) ⇒ Object



365
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 365

def post(path, *args, &block)    route 'POST',    path, *args, &block end

#process_path_for_parent_params(path, parent_params) ⇒ Object

Processes the existing path and prepends the 'parent' parameters onto the route Used for calculating path in route method.



388
389
390
391
392
393
394
395
396
397
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 388

def process_path_for_parent_params(path, parent_params)
  parent_prefix = parent_params.flatten.compact.uniq.map do |param|
    map  = (param.respond_to?(:map) && param.map ? param.map : param.to_s)
    part = "#{map}/:#{Inflections.singularize(param)}_id/"
    part = "(#{part})?" if param.respond_to?(:optional) && param.optional?
    part
  end

  [parent_prefix, path].flatten.join("")
end

#put(path, *args, &block) ⇒ Object



364
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 364

def put(path, *args, &block)     route 'PUT',     path, *args, &block end

#rebase_url(url) ⇒ Object



373
374
375
376
377
378
379
380
381
382
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 373

def rebase_url(url)
  if url.start_with?('/')
    new_url = ''
    new_url << conform_uri(ENV['RACK_BASE_URI']) if ENV['RACK_BASE_URI']
    new_url << conform_uri(uri_root) if defined?(uri_root)
    new_url << url
  else
    url.empty? ? '/' : url
  end
end

#recognize_path(path) ⇒ Symbol, Hash

Recognize a given path.

Examples:

Giving a controller like:

controller :foo do
  get :bar, :map => 'foo-bar-:id'; ...; end
end

You should be able to reverse:

MyApp.url(:foo_bar, :id => :mine)
# => /foo-bar-mine

Into this:

MyApp.recognize_path('foo-bar-mine')
# => [:foo_bar, :id => :mine]

Parameters:

  • path (String)

    Path+Query to parse

Returns:

  • (Symbol, Hash)

    Returns controller and query params.



319
320
321
322
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 319

def recognize_path(path)
  responses = @router.recognize_path(path)
  [responses[0], responses[1]]
end

#reset_router!Object



292
293
294
295
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 292

def reset_router!
  @deferred_routes = nil
  router.reset!
end

#routerObject Also known as: urls

Using PathRouter, for features and configurations.

Examples:

router.add('/greedy/:greed')
router.recognize('/simple')


268
269
270
271
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 268

def router
  @router ||= PathRouter.new
  block_given? ? yield(@router) : @router
end


371
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 371

def unlink(path, *args, &block)  route 'UNLINK',  path, *args, &block end

#url(*args) ⇒ Object Also known as: url_for

Instance method for url generation.

Examples:

url(:show, :id => 1)
url(:show, :name => 'test', :id => 24)
url(:show, 1)
url(:controller_name, :show, :id => 21)
url(:controller_show, :id => 29)
url(:index, :fragment => 'comments')

Parameters:

  • options (Hash)

    a customizable set of options



340
341
342
343
344
345
# File 'padrino-core/lib/padrino-core/application/routing.rb', line 340

def url(*args)
  params = args.last.is_a?(Hash) ? args.pop : {}
  fragment = params.delete(:fragment) || params.delete(:anchor)
  path = make_path_with_params(args, value_to_param(params))
  rebase_url(fragment ? path << '#' << fragment.to_s : path)
end