Created
June 28, 2009 19:56
-
-
Save gabe/137356 to your computer and use it in GitHub Desktop.
Routing & URI generation using URI Templates in Sinatra
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(extendee) | |
extendee.reset_uri_templates! | |
extendee.helpers(Helpers) | |
end | |
module Helpers | |
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment