Skip to content
This repository
Browse code

add multi route extension

commit 12b184d170428ca3ac1abd2100df57b5aad46cae 1 parent 563b242
Konstantin Haase authored
3  README.md
Source Rendered
@@ -39,6 +39,9 @@ Currently included:
39 39
   corresponding `Link` HTTP headers. Adds `link`, `stylesheet` and `prefetch`
40 40
   helper methods.
41 41
 
  42
+* `sinatra/multi_route`: Adds ability to define one route block for multiple
  43
+  routes and multiple or custom HTTP verbs.
  44
+
42 45
 * `sinatra/namespace`: Adds namespace support to Sinatra.
43 46
 
44 47
 * `sinatra/respond_with`: Choose action and/or template depending automatically
1  lib/sinatra/contrib.rb
@@ -8,6 +8,7 @@ module Contrib
8 8
     # Sinatra::Application by default.
9 9
     module Common
10 10
       register :ConfigFile
  11
+      register :MultiRoute
11 12
       register :Namespace
12 13
       register :RespondWith
13 14
 
81  lib/sinatra/multi_route.rb
... ...
@@ -0,0 +1,81 @@
  1
+require 'sinatra/base'
  2
+
  3
+module Sinatra
  4
+  # = Sinatra::MultiRoute
  5
+  #
  6
+  # Create multiple routes with one statement.
  7
+  #
  8
+  # == Usage
  9
+  #
  10
+  # Use this extension to create a handler for multiple routes:
  11
+  #
  12
+  #   get '/foo', '/bar' do
  13
+  #     # ...
  14
+  #   end
  15
+  #
  16
+  # Or for multiple verbs:
  17
+  #
  18
+  #   route :get, :post, '/' do
  19
+  #     # ...
  20
+  #   end
  21
+  #
  22
+  # Or even for custom verbs:
  23
+  #
  24
+  #   route 'LIST', '/' do
  25
+  #     # ...
  26
+  #   end
  27
+  #
  28
+  # === Classic Application
  29
+  #
  30
+  # To use the extension in a classic application all you need to do is require
  31
+  # it:
  32
+  #
  33
+  #     require "sinatra"
  34
+  #     require "sinatra/multi_route"
  35
+  #
  36
+  #     # Your classic application code goes here...
  37
+  #
  38
+  # === Modular Application
  39
+  #
  40
+  # To use the extension in a modular application you need to require it, and
  41
+  # then, tell the application you will use it:
  42
+  #
  43
+  #     require "sinatra/base"
  44
+  #     require "sinatra/multi_route"
  45
+  #
  46
+  #     class MyApp < Sinatra::Base
  47
+  #       register Sinatra::MultiRoute
  48
+  #
  49
+  #       # The rest of your modular application code goes here...
  50
+  #     end
  51
+  #
  52
+  module MultiRoute
  53
+    def head(*args, &block)     super(*route_args(args), &block)  end
  54
+    def delete(*args, &block)   super(*route_args(args), &block)  end
  55
+    def get(*args, &block)      super(*route_args(args), &block)  end
  56
+    def options(*args, &block)  super(*route_args(args), &block)  end
  57
+    def patch(*args, &block)    super(*route_args(args), &block)  end
  58
+    def post(*args, &block)     super(*route_args(args), &block)  end
  59
+    def put(*args, &block)      super(*route_args(args), &block)  end
  60
+
  61
+    def route(*args, &block)
  62
+      options = Hash === args.last ? args.pop : {}
  63
+      routes = [*args.pop]
  64
+      args.each do |verb|
  65
+        verb = verb.to_s.upcase if Symbol === verb
  66
+        routes.each do |route|
  67
+          super(verb, route, options, &block)
  68
+        end
  69
+      end
  70
+    end
  71
+
  72
+    private
  73
+
  74
+    def route_args(args)
  75
+      options = Hash === args.last ? args.pop : {}
  76
+      [args, options]
  77
+    end
  78
+  end
  79
+
  80
+  register MultiRoute
  81
+end
5  lib/sinatra/reloader.rb
@@ -234,7 +234,10 @@ module BaseMethods
234 234
       # Does everything Sinatra::Base#route does, but it also tells the
235 235
       # +Watcher::List+ for the Sinatra application to watch the defined
236 236
       # route.
237  
-      def route(verb, path, options={}, &block)
  237
+      #
  238
+      # Note: We are using #compile! so we don't interfere with extensions
  239
+      # changing #route.
  240
+      def compile!(verb, path, block, options = {})
238 241
         source_location = block.respond_to?(:source_location) ?
239 242
           block.source_location.first : caller_files[1]
240 243
         signature = super
45  spec/multi_route_spec.rb
... ...
@@ -0,0 +1,45 @@
  1
+require 'backports'
  2
+require_relative 'spec_helper'
  3
+
  4
+describe Sinatra::MultiRoute do
  5
+  before do
  6
+    count = 0
  7
+    mock_app do
  8
+      set(:some_condition) { count += 1 }
  9
+      register Sinatra::MultiRoute
  10
+      get('/') { 'normal' }
  11
+      get('/foo', '/bar', :some_condition => true) { 'paths' }
  12
+      route('PUT', 'POST', '/') { 'verb' }
  13
+      route(:get, '/baz') { 'symbol as verb' }
  14
+    end
  15
+    @count = count
  16
+  end
  17
+
  18
+  it 'does still allow normal routing' do
  19
+    get('/').should be_ok
  20
+    body.should be == 'normal'
  21
+  end
  22
+
  23
+  it 'supports multpile routes' do
  24
+    get('/foo').should be_ok
  25
+    body.should be == 'paths'
  26
+    get('/bar').should be_ok
  27
+    body.should be == 'paths'
  28
+  end
  29
+
  30
+  it 'triggers conditions' do
  31
+    @count.should be == 4
  32
+  end
  33
+
  34
+  it 'supports multpile verbs' do
  35
+    post('/').should be_ok
  36
+    body.should be == 'verb'
  37
+    put('/').should be_ok
  38
+    body.should be == 'verb'
  39
+  end
  40
+
  41
+  it 'takes symbols as verbs' do
  42
+    get('/baz').should be_ok
  43
+    body.should be == 'symbol as verb'
  44
+  end
  45
+end

1 note on commit 12b184d

Ryan Sobol

+1 for the multi route syntax

Please sign in to comment.
Something went wrong with that request. Please try again.