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 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
@@ -0,0 +1,5 @@
1
+ module Sinatra
2
+ module BlueRoutes
3
+ VERSION = '0.1.0'
4
+ end
5
+ 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: []