This extension is part of the Sinatra::Contrib project. Run gem install sinatra-contrib to have it available.

Sinatra::Namespace

Sinatra::Namespace is an extension that adds namespaces to an application. This namespaces will allow you to share a path prefix for the routes within the namespace, and define filters, conditions and error handlers exclusively for them. Besides that, you can also register helpers and extensions that will be used only within the namespace.

Usage

Once you have loaded the extension (see below), you can use the namespace method to define namespaces in your application.

You can define a namespace by a path prefix:

namespace '/blog' do
  get { haml :blog }
  get '/:entry_permalink' do
    @entry = Entry.find_by_permalink!(params[:entry_permalink])
    haml :entry
  end

  # More blog routes...
end

by a condition:

namespace :host_name => 'localhost' do
  get('/admin/dashboard') { haml :dashboard }
  get('/admin/login')     { haml :login }

  # More admin routes...
end

or both:

namespace '/admin', :host_name => 'localhost' do
  get('/dashboard')  { haml :dashboard }
  get('/login')      { haml :login }
  post('/login')     { login_user }

  # More admin routes...
end

Regex is also accepted:

namespace /\/posts\/([^\/&?]+)\// do
  get { haml :blog }

  # More blog routes...
end

When you define a filter or an error handler, or register an extension or a set of helpers within a namespace, they only affect the routes defined in it. For instance, lets define a before filter to prevent the access of unauthorized users to the admin section of the application:

namespace '/admin' do
  helpers AdminHelpers
  before  { authenticate unless request.path_info == '/admin/login' }

  get '/dashboard' do
    # Only authenticated users can access here...
    haml :dashboard
  end

  # More admin routes...
end

get '/' do
  # Any user can access here...
  haml :index
end

Well, they actually also affect the nested namespaces:

namespace '/admin' do
  helpers AdminHelpers
  before  { authenticate unless request.path_info == '/admin/login' }

  namespace '/users' do
    get do
      # Only authenticated users can access here...
      @users = User.all
      haml :users
    end

    # More user admin routes...
  end

  # More admin routes...
end

Redirecting within the namespace can be done using redirect_to:

namespace '/admin' do
  get '/foo'  do
    redirect_to '/bar' # Redirects to /admin/bar
  end

  get '/foo' do
    redirect '/bar' # Redirects to /bar
  end
end

Classic Application Setup

To be able to use namespaces in a classic application all you need to do is require the extension:

require "sinatra"
require "sinatra/namespace"

namespace '/users' do
end

Modular Application Setup

To be able to use namespaces in a modular application all you need to do is require the extension, and then, register it:

require "sinatra/base"
require "sinatra/namespace"

class MyApp < Sinatra::Base
  register Sinatra::Namespace

  namespace '/users' do
  end
end

Within an extension

To be able to use namespaces within an extension, you need to first create an extension. This includes defining the `registered(app)` method in the module.

require 'sinatra/base' # For creating Sinatra extensions
require 'sinatra/namespace' # To create namespaces

module Zomg # Keep everything under "Zomg" namespace for sanity
  module Routes # Define a new "Routes" module

    self.registered(app)
      # First, register the Namespace extension
      app.register Sinatra::Namespace

      # This defines an `/api` namespace on the application
      app.namespace '/api' do
        get '/users' do
          # do something with `GET "/api/users"`
        end
      end

    end
  end

  # Lastly, register the extension to use in our app
  Sinatra.register Routes
end

In order to use this extension, is the same as any other Sinatra extension:

module Zomg
  # Define our app class, we use modular app for this example
  class App < Sinatra::Base
    # this gives us all the namespaces we defined earlier
    register Routes

    get '/' do
      "Welcome to my application!"
    end
  end
end

Zomg::App.run! # Don't forget to start your app ;)

Phew! That was a mouthful.

I hope that helps you use `Sinatra::Namespace` in every way imaginable!