sinatra-named-routes-subdomains 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +15 -0
- data/README.md +14 -0
- data/lib/sinatra/named_routes.rb +72 -0
- data/lib/sinatra/route_parser.rb +175 -0
- data/lib/sinatra/version.rb +5 -0
- data/sinatra-named-routes-0.1.0.gem +0 -0
- data/sinatra-named-routes-subdomains.gemspec +22 -0
- metadata +72 -0
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in sinatra-named-routes.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development, :test do
|
7
|
+
gem 'rake'
|
8
|
+
gem 'sinatra-contrib'
|
9
|
+
gem 'rspec'
|
10
|
+
gem 'guard-rspec'
|
11
|
+
end
|
12
|
+
|
13
|
+
group :test do
|
14
|
+
gem 'simplecov', :require => false
|
15
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Sinatra Named Routes w/ Subdomain support
|
2
|
+
|
3
|
+
Based on sinatra-named-routes by ckhampus: https://github.com/ckhampus/sinatra-named-routes.
|
4
|
+
|
5
|
+
## Subdomain Usage
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
map :named_route, '/myroute/:some_id'
|
9
|
+
url( :named_route, true, :some_id => 123, :subdomain => 'mysubdomain' )
|
10
|
+
```
|
11
|
+
|
12
|
+
```
|
13
|
+
http://mysubdomain.myhost.com/myroute/123
|
14
|
+
```
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'version')
|
2
|
+
require File.join(File.dirname(__FILE__), 'route_parser')
|
3
|
+
|
4
|
+
module Sinatra
|
5
|
+
module NamedRoutes
|
6
|
+
module Helpers
|
7
|
+
|
8
|
+
# Generates the absolute URI for a given path in the app.
|
9
|
+
# Takes Rack routers and reverse proxies into account.
|
10
|
+
# Extended support passing in named route and parameters.
|
11
|
+
def uri( addr = nil, absolute = true, params = nil )
|
12
|
+
if addr.is_a? Symbol
|
13
|
+
addr = NamedRoutes.get_path( addr, params )
|
14
|
+
end
|
15
|
+
|
16
|
+
return addr if addr =~ /\A[A-z][A-z0-9\+\.\-]*:/
|
17
|
+
|
18
|
+
uri = [host = ""]
|
19
|
+
if absolute
|
20
|
+
host << "http#{'s' if request.secure?}://"
|
21
|
+
if request.forwarded? or request.port != (request.secure? ? 443 : 80)
|
22
|
+
domain = request.host_with_port
|
23
|
+
else
|
24
|
+
domain = request.host
|
25
|
+
end
|
26
|
+
|
27
|
+
if !params.nil? && !params[:subdomain].nil?
|
28
|
+
host << domain.gsub(/^([a-zA-Z-]+)\./, "#{params[:subdomain]}.")
|
29
|
+
else
|
30
|
+
host << domain
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
uri << (addr ? addr : request.path_info).to_s
|
35
|
+
File.join uri
|
36
|
+
end
|
37
|
+
|
38
|
+
alias :to :uri
|
39
|
+
alias :url :uri
|
40
|
+
end
|
41
|
+
|
42
|
+
# Maps a path to name.
|
43
|
+
def map(name, path)
|
44
|
+
NamedRoutes.routes[name] = Route.new path
|
45
|
+
end
|
46
|
+
|
47
|
+
alias :bind :map
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def route(verb, path, options={}, &block)
|
52
|
+
if path.is_a?(Symbol)
|
53
|
+
path = NamedRoutes.routes[path].source
|
54
|
+
end
|
55
|
+
|
56
|
+
super(verb, path, options, &block)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.get_path(name, params = {})
|
60
|
+
raise ArgumentError, "No route with the name #{name} exists." if NamedRoutes.routes.nil?
|
61
|
+
NamedRoutes.routes[name].build params
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.routes
|
65
|
+
@@routes ||= {}
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.registered(app)
|
69
|
+
app.helpers NamedRoutes::Helpers
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
module Sinatra
|
2
|
+
module BlueRoutes
|
3
|
+
class Route
|
4
|
+
attr_reader :source
|
5
|
+
|
6
|
+
def initialize(route)
|
7
|
+
route = route.source if route.is_a? Regexp
|
8
|
+
|
9
|
+
@source = route
|
10
|
+
@input = StringScanner.new(route)
|
11
|
+
@output = []
|
12
|
+
|
13
|
+
parse
|
14
|
+
end
|
15
|
+
|
16
|
+
def build(params = {})
|
17
|
+
path = []
|
18
|
+
params = {} if params.nil?
|
19
|
+
|
20
|
+
@output.each_index do |index|
|
21
|
+
item = @output[index]
|
22
|
+
next_item = @output.fetch(index + 1, nil)
|
23
|
+
|
24
|
+
case item[:token]
|
25
|
+
when :slash
|
26
|
+
@trailing_slash = item[:optional]
|
27
|
+
path << '/'
|
28
|
+
when :dot
|
29
|
+
@trailing_dot = item[:optional]
|
30
|
+
path << '.'
|
31
|
+
when :plus
|
32
|
+
path << '+'
|
33
|
+
when :splat
|
34
|
+
if params.is_a? Hash
|
35
|
+
raise ArgumentError, 'No parameters passed.' if params[:splat].empty?
|
36
|
+
path << params[:splat].shift
|
37
|
+
else
|
38
|
+
raise ArgumentError, 'No enough parameters passed.' if params.empty?
|
39
|
+
path << params.shift
|
40
|
+
end
|
41
|
+
when :path
|
42
|
+
path << item[:value]
|
43
|
+
when :named_param
|
44
|
+
item_key = item[:value]
|
45
|
+
|
46
|
+
if params.has_key? item_key
|
47
|
+
path << params.delete(item_key)
|
48
|
+
else
|
49
|
+
raise ArgumentError, "No value passed for '#{item_key.to_s}'" unless item[:optional]
|
50
|
+
end
|
51
|
+
when :regexp
|
52
|
+
name = /#{item[:value]}/.names
|
53
|
+
|
54
|
+
if name.any?
|
55
|
+
name = name.first.to_sym
|
56
|
+
|
57
|
+
if params.has_key? name
|
58
|
+
path << params.delete(name)
|
59
|
+
else
|
60
|
+
raise ArgumentError, "No value passed for '#{name.to_s}'" unless item[:optional]
|
61
|
+
end
|
62
|
+
else
|
63
|
+
if params.is_a? Hash
|
64
|
+
raise ArgumentError, 'No enough parameters passed.' if params[:captures].empty? and !item[:optional]
|
65
|
+
path << params[:captures].shift
|
66
|
+
else
|
67
|
+
raise ArgumentError, 'No enough parameters passed.' if params.empty?
|
68
|
+
path << params.shift
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
path = path.join
|
75
|
+
|
76
|
+
if @trailing_dot
|
77
|
+
path = path.chomp '.'
|
78
|
+
end
|
79
|
+
|
80
|
+
if @trailing_slash
|
81
|
+
path = path.chomp '/'
|
82
|
+
end
|
83
|
+
|
84
|
+
path
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def is_optional?
|
90
|
+
@output.last[:optional] = @input.scan(/\?/) ? true : false
|
91
|
+
end
|
92
|
+
|
93
|
+
def parse
|
94
|
+
while token = parse_slash || parse_path || parse_named_param ||
|
95
|
+
parse_dot || parse_plus || parse_splat || parse_regexp
|
96
|
+
@output << token
|
97
|
+
is_optional?
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def parse_slash
|
102
|
+
if @input.scan(/\//)
|
103
|
+
{
|
104
|
+
:token => :slash
|
105
|
+
}
|
106
|
+
else
|
107
|
+
nil
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def parse_dot
|
112
|
+
if @input.scan(/\./)
|
113
|
+
{
|
114
|
+
:token => :dot
|
115
|
+
}
|
116
|
+
else
|
117
|
+
nil
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def parse_plus
|
122
|
+
if @input.scan(/\+/)
|
123
|
+
{
|
124
|
+
:token => :plus
|
125
|
+
}
|
126
|
+
else
|
127
|
+
nil
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def parse_splat
|
132
|
+
if @input.scan(/\*/)
|
133
|
+
{
|
134
|
+
:token => :splat
|
135
|
+
}
|
136
|
+
else
|
137
|
+
nil
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def parse_path
|
142
|
+
if @input.scan(/\w+/)
|
143
|
+
{
|
144
|
+
:token => :path,
|
145
|
+
:value => @input.matched
|
146
|
+
}
|
147
|
+
else
|
148
|
+
nil
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def parse_named_param
|
153
|
+
if @input.scan(/:[^\W]*/)
|
154
|
+
{
|
155
|
+
:token => :named_param,
|
156
|
+
:value => @input.matched.sub(':', '').to_sym
|
157
|
+
}
|
158
|
+
else
|
159
|
+
nil
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def parse_regexp
|
164
|
+
if @input.scan(/\([^\)]*\)/)
|
165
|
+
{
|
166
|
+
:token => :regexp,
|
167
|
+
:value => @input.matched
|
168
|
+
}
|
169
|
+
else
|
170
|
+
nil
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
Binary file
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 'sinatra/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'sinatra-named-routes-subdomains'
|
7
|
+
s.version = Sinatra::BlueRoutes::VERSION
|
8
|
+
s.authors = ['Adam Zerlin']
|
9
|
+
s.email = ['adam@adamzerlin.com']
|
10
|
+
s.homepage = 'https://github.com/adamzerlin/sinatra-named-routes'
|
11
|
+
s.summary = %q{Named Routes for Sinatra with Subdomains}
|
12
|
+
s.description = %q{Allows the use of named routes and custom subdomains in Sinatra applications. Based heavily on ckhampus' sinatra-named-routes.}
|
13
|
+
|
14
|
+
s.rubyforge_project = 'sinatra-named-routes-subdomains'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ['lib']
|
20
|
+
|
21
|
+
s.add_dependency 'sinatra'
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sinatra-named-routes-subdomains
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Adam Zerlin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-01 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: sinatra
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: !binary |-
|
21
|
+
MA==
|
22
|
+
none: false
|
23
|
+
requirement: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: !binary |-
|
28
|
+
MA==
|
29
|
+
none: false
|
30
|
+
prerelease: false
|
31
|
+
type: :runtime
|
32
|
+
description: Allows the use of named routes and custom subdomains in Sinatra applications. Based heavily on ckhampus' sinatra-named-routes.
|
33
|
+
email:
|
34
|
+
- adam@adamzerlin.com
|
35
|
+
executables: []
|
36
|
+
extensions: []
|
37
|
+
extra_rdoc_files: []
|
38
|
+
files:
|
39
|
+
- Gemfile
|
40
|
+
- README.md
|
41
|
+
- lib/sinatra/named_routes.rb
|
42
|
+
- lib/sinatra/route_parser.rb
|
43
|
+
- lib/sinatra/version.rb
|
44
|
+
- sinatra-named-routes-0.1.0.gem
|
45
|
+
- sinatra-named-routes-subdomains.gemspec
|
46
|
+
homepage: https://github.com/adamzerlin/sinatra-named-routes
|
47
|
+
licenses: []
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: !binary |-
|
57
|
+
MA==
|
58
|
+
none: false
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: !binary |-
|
64
|
+
MA==
|
65
|
+
none: false
|
66
|
+
requirements: []
|
67
|
+
rubyforge_project: sinatra-named-routes-subdomains
|
68
|
+
rubygems_version: 1.8.24
|
69
|
+
signing_key:
|
70
|
+
specification_version: 3
|
71
|
+
summary: Named Routes for Sinatra with Subdomains
|
72
|
+
test_files: []
|