sr (owner)

Fork Of

gist: 137356 by gabe Routing & URI generation us...

Revisions

gist: 138504 Download_button fork
public
Description:
bookmarked
Public Clone URL: git://gist.github.com/138504.git
Embed All Files: show embed
Ruby #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
require 'addressable/template'
 
module Juxt
  module Sinatra
    # Allows for declared, named URI Templates in Sinatra applications,
    # for both routing and URI generation.
    #
    # The URI generation method (included as a Sinatra helper) modifies
    # the path of generated URIs with request.script_name, meaning the
    # URIs generated will still be valid if multiple Sinatra applications
    # are hosted in the same application, using Rack::Builder.
    #
    # Requires Addressable (http://github.com/sporkmonger/addressable/tree/master).
    #
    # == Example
    #
    # class MyApplication < Sinatra::Base
    # extend Juxt::Sinatra::URITemplates
    #
    # uri :index, '/'
    # uri :entry, '/entries/{id}'
    #
    # get :index do
    # "Hello"
    # end
    #
    # get :entry do
    # "The URI of this entry is #{uri(:entry, 'id' => params[:id])}"
    # end
    # end
    module URITemplates
      def reset_uri_templates!
        @uri_templates = {}
      end
    
      # Declare a named URI Template for use in this application, and
      # in subclasses of this application.
      def uri(name, template)
        @uri_templates[name] = Addressable::Template.new(template)
      end
    
      # Gets the merged URI Template collection for this application,
      # and all superclasses.
      def uri_templates
        if superclass.respond_to?(:uri_templates)
          superclass.uri_templates.merge(@uri_templates)
        else
          @uri_templates
        end
      end
    
      private
    
      # Override Sinatra route compilation (dirty).
      def compile(path)
        super(uri_templates[path] || path)
      end
    
      def inherited(subclass)
        subclass.reset_uri_templates!
        super
      end
    
      # Initialize the URI Template collection for the application
      # being extended, and add a Sinatra helper for expanding
      # templates, by name.
      def self.extended(base)
        base.reset_uri_templates!
        base.helpers do
          def uri(name, *args)
            template = self.class.uri_templates[name]
            if template.nil?
              return nil
            end
            args[0] ||= {}
            uri = template.expand(*args)
            uri.path = request.script_name + uri.path
            uri
          end
        end
      end
    end
  end
end