subdomain-fu 0.4.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/CHANGELOG +13 -0
- data/MIT-LICENSE +21 -0
- data/README.rdoc +96 -0
- data/Rakefile +27 -0
- data/VERSION.yml +4 -0
- data/lib/subdomain-fu.rb +150 -0
- data/lib/subdomain_fu/routing_extensions.rb +61 -0
- data/lib/subdomain_fu/url_rewriter.rb +48 -0
- data/rails/init.rb +8 -0
- data/spec/spec.opts +7 -0
- data/spec/spec_helper.rb +42 -0
- data/spec/subdomain_fu_spec.rb +217 -0
- data/spec/url_rewriter_spec.rb +149 -0
- metadata +69 -0
data/CHANGELOG
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2008 Michael Bleigh (http://www.mbleigh.com) and
|
2
|
+
Intridea, Inc (http://www.intridea.com)
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
= SubdomainFu
|
2
|
+
|
3
|
+
SubdomainFu provides a modern implementation of subdomain handling in Rails.
|
4
|
+
It takes aspects from account_location, request_routing, and other snippets
|
5
|
+
found around the web and combines them to provide a single, simple solution
|
6
|
+
for subdomain-based route and url management.
|
7
|
+
|
8
|
+
== Installation
|
9
|
+
|
10
|
+
SubdomainFu is available both as a traditional plugin and a GemPlugin. To
|
11
|
+
install it as a traditional plugin (Rails 2.1 or later):
|
12
|
+
|
13
|
+
script/plugin install git://github.com/mbleigh/subdomain-fu.git
|
14
|
+
|
15
|
+
To use it as a GemPlugin, add it to your environment.rb:
|
16
|
+
|
17
|
+
config.gem 'mbleigh-subdomain-fu', :source => "http://gems.github.com", :lib => "subdomain-fu"
|
18
|
+
|
19
|
+
|
20
|
+
== Examples
|
21
|
+
|
22
|
+
SubdomainFu works inside of Rails's URL Writing mechanisms to provide an easy and seamless
|
23
|
+
way to link and otherwise understand cross-subdomain routing. You can use the :subdomain
|
24
|
+
option both in named and non-named routes as well as in generated resources routes.
|
25
|
+
|
26
|
+
Let's say my domain is 'intridea.com'. Here are some examples of the use of the :subdomain
|
27
|
+
option:
|
28
|
+
|
29
|
+
url_for(:controller => "my_controller",
|
30
|
+
:action => "my_action",
|
31
|
+
:subdomain => "awesome") # => http://awesome.intridea.com/my_controller/my_action
|
32
|
+
|
33
|
+
Now let's say I'm at http://awesome.intridea.com/ and I want back to the root.
|
34
|
+
Specifying "false" will remove any current subdomain:
|
35
|
+
|
36
|
+
users_url(:subdomain => false) # => http://intridea.com/users
|
37
|
+
|
38
|
+
Note that this plugin does not honor the :only_path notion of routing when doing
|
39
|
+
so would go against the intent of the command. For example, if I were at http://intridea.com
|
40
|
+
again:
|
41
|
+
|
42
|
+
users_path(:subdomain => "fun") # => http://fun.intridea.com/users
|
43
|
+
users_path(:subdomain => false) # => /users
|
44
|
+
|
45
|
+
In this way you can rest assured that you will never misdirect your links to the
|
46
|
+
same subdomain when you meant to change it.
|
47
|
+
|
48
|
+
== Configuration
|
49
|
+
|
50
|
+
You may need to configure SubdomainFu based on your development setup. The
|
51
|
+
configuration required is:
|
52
|
+
|
53
|
+
=== TLD Size
|
54
|
+
|
55
|
+
A hash for each environment of the size of the top-level domain name.
|
56
|
+
(something.com = 1, localhost = 0, etc.)
|
57
|
+
|
58
|
+
SubdomainFu.tld_size = 1 # sets for current environment
|
59
|
+
SubdomainFu.tld_sizes = {:development => 0,
|
60
|
+
:test => 0,
|
61
|
+
:production => 1} # set all at once (also the defaults)
|
62
|
+
|
63
|
+
=== Mirrors
|
64
|
+
|
65
|
+
Mirrors are the subdomains that are equivalent to no subdomain (i.e. they 'mirror')
|
66
|
+
the usage of the root domain.
|
67
|
+
|
68
|
+
SubdomainFu.mirrors = %w(www site we) # Defaults to %w(www)
|
69
|
+
|
70
|
+
=== Preferred Mirror
|
71
|
+
|
72
|
+
SubdomainFu also understands the notion of a 'preferred mirror', that is, if you
|
73
|
+
always want your links going to 'www.yourdomain.com' instead of 'yourdomain.com',
|
74
|
+
you can set the preferred mirror like so:
|
75
|
+
|
76
|
+
SubdomainFu.preferred_mirror = "www"
|
77
|
+
|
78
|
+
Now when you create a link with subdomain => false in the options the subdomain
|
79
|
+
will default to the preferred mirror.
|
80
|
+
|
81
|
+
== Routing
|
82
|
+
|
83
|
+
SubdomainFu can also work within Rails' routing for subdomain-specific routes. For instance, if you only wanted your administrative tools available in the "admin" subdomain you could add this to your routes.rb file:
|
84
|
+
|
85
|
+
map.with_options :conditions => {:subdomain => 'admin} do |admin|
|
86
|
+
admin.resources :posts
|
87
|
+
admin.resources :users
|
88
|
+
end
|
89
|
+
|
90
|
+
== Resources
|
91
|
+
|
92
|
+
* GitHub Repository: http://github.com/mbleigh/subdomain-fu
|
93
|
+
* RDocs: http://rdoc.info/projects/mbleigh/subdomain-fu
|
94
|
+
|
95
|
+
Copyright (c) 2008 Michael Bleigh (http://www.mbleigh.com/) and
|
96
|
+
Intridea, Inc. (http://www.intridea.com/). Released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'spec/rake/spectask'
|
3
|
+
|
4
|
+
desc 'Default: run specs.'
|
5
|
+
task :default => :spec
|
6
|
+
|
7
|
+
desc 'Run the specs'
|
8
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
9
|
+
t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
|
10
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
11
|
+
end
|
12
|
+
|
13
|
+
begin
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gemspec|
|
16
|
+
gemspec.name = "subdomain-fu"
|
17
|
+
gemspec.summary = "SubdomainFu is a Rails plugin that provides subdomain routing and URL writing helpers."
|
18
|
+
gemspec.email = "michael@intridea.com"
|
19
|
+
gemspec.homepage = "http://github.com/mbleigh/subdomain-fu"
|
20
|
+
gemspec.files = FileList["[A-Z]*", "{lib,spec,rails}/**/*"] - FileList["**/*.log"]
|
21
|
+
gemspec.description = "SubdomainFu is a Rails plugin to provide all of the basic functionality necessary to handle multiple subdomain applications (such as Basecamp-esque subdomain accounts and more)."
|
22
|
+
gemspec.authors = ["Michael Bleigh"]
|
23
|
+
end
|
24
|
+
rescue LoadError
|
25
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
26
|
+
end
|
27
|
+
|
data/VERSION.yml
ADDED
data/lib/subdomain-fu.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'subdomain_fu/routing_extensions'
|
2
|
+
require 'subdomain_fu/url_rewriter'
|
3
|
+
|
4
|
+
module SubdomainFu
|
5
|
+
# The length of the period-split top-level domain for each environment.
|
6
|
+
# For example, "localhost" has a tld_size of zero, and "something.co.uk"
|
7
|
+
# has a tld_size of two.
|
8
|
+
#
|
9
|
+
# To set a tld size for a given environment, just call SubdomainFu.tld_sizes[:environment] = value
|
10
|
+
DEFAULT_TLD_SIZES = {:development => 0, :test => 0, :production => 1}
|
11
|
+
mattr_accessor :tld_sizes
|
12
|
+
@@tld_sizes = DEFAULT_TLD_SIZES.dup
|
13
|
+
|
14
|
+
# Subdomains that are equivalent to going to the website with no subdomain at all.
|
15
|
+
# Defaults to "www" as the only member.
|
16
|
+
DEFAULT_MIRRORS = %w(www)
|
17
|
+
mattr_accessor :mirrors
|
18
|
+
@@mirrors = DEFAULT_MIRRORS.dup
|
19
|
+
|
20
|
+
mattr_accessor :preferred_mirror
|
21
|
+
@@preferred_mirror = nil
|
22
|
+
|
23
|
+
mattr_accessor :override_only_path
|
24
|
+
@@override_only_path = false
|
25
|
+
|
26
|
+
# Returns the TLD Size of the current environment.
|
27
|
+
def self.tld_size
|
28
|
+
tld_sizes[RAILS_ENV.to_sym]
|
29
|
+
end
|
30
|
+
|
31
|
+
# Sets the TLD Size of the current environment
|
32
|
+
def self.tld_size=(value)
|
33
|
+
tld_sizes[RAILS_ENV.to_sym] = value
|
34
|
+
end
|
35
|
+
|
36
|
+
# Is the current subdomain either nil or not a mirror?
|
37
|
+
def self.has_subdomain?(subdomain)
|
38
|
+
subdomain != false && !subdomain.blank? && !SubdomainFu.mirrors.include?(subdomain)
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.is_mirror?(subdomain)
|
42
|
+
subdomain != false && !subdomain.blank? && SubdomainFu.mirrors.include?(subdomain)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Is the subdomain a preferred mirror
|
46
|
+
def self.preferred_mirror?(subdomain)
|
47
|
+
subdomain == SubdomainFu.preferred_mirror || SubdomainFu.preferred_mirror.nil?
|
48
|
+
end
|
49
|
+
|
50
|
+
# Gets the subdomain from the host based on the TLD size
|
51
|
+
def self.subdomain_from(host)
|
52
|
+
return nil if host.nil? || /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.match(host)
|
53
|
+
parts = host.split('.')
|
54
|
+
sub = parts[0..-(SubdomainFu.tld_size+2)].join(".")
|
55
|
+
sub.blank? ? nil : sub
|
56
|
+
end
|
57
|
+
|
58
|
+
# Gets only non-mirror subdomains from the host based on the TLD size
|
59
|
+
def self.non_mirror_subdomain_from(host)
|
60
|
+
sub = subdomain_from(host)
|
61
|
+
has_subdomain?(sub) ? sub : nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.host_without_subdomain(host)
|
65
|
+
parts = host.split('.')
|
66
|
+
parts[-(SubdomainFu.tld_size+1)..-1].join(".")
|
67
|
+
end
|
68
|
+
|
69
|
+
# Rewrites the subdomain of the host unless they are equivalent (i.e. mirrors of each other)
|
70
|
+
def self.rewrite_host_for_subdomains(subdomain, host)
|
71
|
+
if needs_rewrite?(subdomain, host)
|
72
|
+
change_subdomain_of_host(subdomain || SubdomainFu.preferred_mirror, host)
|
73
|
+
else
|
74
|
+
if has_subdomain?(subdomain) || preferred_mirror?(subdomain_from(host)) ||
|
75
|
+
(subdomain.nil? && has_subdomain?(subdomain_from(host)))
|
76
|
+
host
|
77
|
+
else
|
78
|
+
change_subdomain_of_host(SubdomainFu.preferred_mirror, host)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Changes the subdomain of the host to whatever is passed in.
|
84
|
+
def self.change_subdomain_of_host(subdomain, host)
|
85
|
+
host = SubdomainFu.host_without_subdomain(host)
|
86
|
+
host = "#{subdomain}.#{host}" if subdomain
|
87
|
+
host
|
88
|
+
end
|
89
|
+
|
90
|
+
# Is this subdomain equivalent to the subdomain found in this host string?
|
91
|
+
def self.same_subdomain?(subdomain, host)
|
92
|
+
subdomain = nil unless subdomain
|
93
|
+
(subdomain == subdomain_from(host)) ||
|
94
|
+
(!has_subdomain?(subdomain) && !has_subdomain?(subdomain_from(host)))
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.override_only_path?
|
98
|
+
self.override_only_path
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.needs_rewrite?(subdomain, host)
|
102
|
+
case subdomain
|
103
|
+
when nil
|
104
|
+
#rewrite when there is a preferred mirror set and there is no subdomain on the host
|
105
|
+
return true if self.preferred_mirror && subdomain_from(host).nil?
|
106
|
+
return false
|
107
|
+
when false
|
108
|
+
h = subdomain_from(host)
|
109
|
+
#if the host has a subdomain
|
110
|
+
if !h.nil?
|
111
|
+
#rewrite when there is a subdomain in the host, and it is not a preferred mirror
|
112
|
+
return true if !preferred_mirror?(h)
|
113
|
+
#rewrite when there is a preferred mirror set and the subdomain of the host is not a mirror
|
114
|
+
return true if self.preferred_mirror && !is_mirror?(h)
|
115
|
+
#no rewrite if host already has mirror subdomain
|
116
|
+
#it { SubdomainFu.needs_rewrite?(false,"www.localhost").should be_false }
|
117
|
+
return false if is_mirror?(h)
|
118
|
+
end
|
119
|
+
return self.crazy_rewrite_rule(subdomain, host)
|
120
|
+
else
|
121
|
+
return self.crazy_rewrite_rule(subdomain, host)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
#This is a black box of crazy! So I split some of the simpler logic out into the case statement above to make my brain happy!
|
126
|
+
def self.crazy_rewrite_rule(subdomain, host)
|
127
|
+
(!has_subdomain?(subdomain) && preferred_mirror?(subdomain) && !preferred_mirror?(subdomain_from(host))) ||
|
128
|
+
!same_subdomain?(subdomain, host)
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.current_subdomain(request)
|
132
|
+
subdomain = request.subdomains(SubdomainFu.tld_size).join(".")
|
133
|
+
if has_subdomain?(subdomain)
|
134
|
+
subdomain
|
135
|
+
else
|
136
|
+
nil
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
module Controller
|
141
|
+
def self.included(controller)
|
142
|
+
controller.helper_method(:current_subdomain)
|
143
|
+
end
|
144
|
+
|
145
|
+
protected
|
146
|
+
def current_subdomain
|
147
|
+
SubdomainFu.current_subdomain(request)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# Thanks to Jamis Buck for ideas on this stuff
|
2
|
+
# http://weblog.jamisbuck.org/2006/10/26/monkey-patching-rails-extending-routes-2
|
3
|
+
# This is not yet a working part of SubdomainFu.
|
4
|
+
|
5
|
+
module SubdomainFu
|
6
|
+
module RouteExtensions
|
7
|
+
def self.included(base)
|
8
|
+
base.alias_method_chain :recognition_conditions, :subdomain
|
9
|
+
end
|
10
|
+
|
11
|
+
def recognition_conditions_with_subdomain
|
12
|
+
result = recognition_conditions_without_subdomain
|
13
|
+
result << "conditions[:subdomain] === env[:subdomain]" if conditions[:subdomain] && conditions[:subdomain] != true && conditions[:subdomain] != false
|
14
|
+
result << "SubdomainFu.has_subdomain?(env[:subdomain])" if conditions[:subdomain] == true
|
15
|
+
result << "!SubdomainFu.has_subdomain?(env[:subdomain])" if conditions[:subdomain] == false
|
16
|
+
result
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module RouteSetExtensions
|
21
|
+
def self.included(base)
|
22
|
+
base.alias_method_chain :extract_request_environment, :subdomain
|
23
|
+
end
|
24
|
+
|
25
|
+
def extract_request_environment_with_subdomain(request)
|
26
|
+
env = extract_request_environment_without_subdomain(request)
|
27
|
+
env.merge(:host => request.host, :domain => request.domain, :subdomain => SubdomainFu.subdomain_from(request.host))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module MapperExtensions
|
32
|
+
def quick_map(has_unless, *args, &block)
|
33
|
+
options = args.find{|a| a.is_a?(Hash)}
|
34
|
+
namespace_str = options ? options.delete(:namespace).to_s : args.join('_or_')
|
35
|
+
namespace_str += '_' unless namespace_str.blank?
|
36
|
+
mapped_exp = args.map(&:to_s).join('|')
|
37
|
+
conditions_hash = { :subdomain => ( has_unless ? /[^(#{mapped_exp})]/ : /(#{mapped_exp})/) }
|
38
|
+
with_options(:conditions => conditions_hash, :name_prefix => namespace_str, &block)
|
39
|
+
end
|
40
|
+
# Adds methods to Mapper to apply an options with a method. Example
|
41
|
+
# map.subdomain :blog { |blog| blog.resources :pages }
|
42
|
+
# or
|
43
|
+
# map.unless_subdomain :blog { |not_blog| not_blog.resources :people }
|
44
|
+
def subdomain(*args, &block)
|
45
|
+
quick_map(false, *args, &block)
|
46
|
+
end
|
47
|
+
def unless_subdomain(*args, &block)
|
48
|
+
quick_map(true, *args, &block)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
ActionController::Routing::RouteSet::Mapper.send :include, SubdomainFu::MapperExtensions
|
54
|
+
ActionController::Routing::RouteSet.send :include, SubdomainFu::RouteSetExtensions
|
55
|
+
ActionController::Routing::Route.send :include, SubdomainFu::RouteExtensions
|
56
|
+
|
57
|
+
# UrlRewriter::RESERVED_OPTIONS is only available in Rails >= 2.2
|
58
|
+
# http://www.portallabs.com/blog/2008/12/02/fixing-subdomain_fu-with-named-routes-rails-22/
|
59
|
+
if Rails::VERSION::MAJOR >= 2 and Rails::VERSION::MINOR >= 2
|
60
|
+
ActionController::UrlRewriter::RESERVED_OPTIONS << :subdomain
|
61
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module ActionController
|
2
|
+
module UrlWriter
|
3
|
+
def url_for_with_subdomains(options)
|
4
|
+
if SubdomainFu.needs_rewrite?(options[:subdomain], options[:host] || default_url_options[:host]) || options[:only_path] == false
|
5
|
+
options[:only_path] = false if SubdomainFu.override_only_path?
|
6
|
+
options[:host] = SubdomainFu.rewrite_host_for_subdomains(options.delete(:subdomain), options[:host] || default_url_options[:host])
|
7
|
+
else
|
8
|
+
options.delete(:subdomain)
|
9
|
+
end
|
10
|
+
url_for_without_subdomains(options)
|
11
|
+
end
|
12
|
+
alias_method_chain :url_for, :subdomains
|
13
|
+
end
|
14
|
+
|
15
|
+
class UrlRewriter #:nodoc:
|
16
|
+
private
|
17
|
+
|
18
|
+
def rewrite_url_with_subdomains(options)
|
19
|
+
if SubdomainFu.needs_rewrite?(options[:subdomain], (options[:host] || @request.host_with_port)) || options[:only_path] == false
|
20
|
+
options[:only_path] = false if SubdomainFu.override_only_path?
|
21
|
+
options[:host] = SubdomainFu.rewrite_host_for_subdomains(options.delete(:subdomain), options[:host] || @request.host_with_port)
|
22
|
+
puts "options[:host]: #{options[:host].inspect}"
|
23
|
+
else
|
24
|
+
options.delete(:subdomain)
|
25
|
+
end
|
26
|
+
rewrite_url_without_subdomains(options)
|
27
|
+
end
|
28
|
+
alias_method_chain :rewrite_url, :subdomains
|
29
|
+
end
|
30
|
+
|
31
|
+
if Rails::VERSION::MAJOR >= 2 and Rails::VERSION::MINOR <= 1
|
32
|
+
# hack for http://www.portallabs.com/blog/2008/10/22/fixing-subdomain_fu-with-named-routes/
|
33
|
+
module Routing
|
34
|
+
module Optimisation
|
35
|
+
class PositionalArgumentsWithAdditionalParams
|
36
|
+
def guard_condition_with_subdomains
|
37
|
+
# don't allow optimisation if a subdomain is present - fixes a problem
|
38
|
+
# with the subdomain appearing in the query instead of being rewritten
|
39
|
+
# see http://mbleigh.lighthouseapp.com/projects/13148/tickets/8-improper-generated-urls-with-named-routes-for-a-singular-resource
|
40
|
+
guard_condition_without_subdomains + " && !args.last.has_key?(:subdomain)"
|
41
|
+
end
|
42
|
+
|
43
|
+
alias_method_chain :guard_condition, :subdomains
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# Add this path to ruby load path
|
2
|
+
$:.unshift "#{File.dirname(__FILE__)}/../lib"
|
3
|
+
|
4
|
+
require 'subdomain-fu' unless defined?(SubdomainFu)
|
5
|
+
|
6
|
+
ActionController::Base.send :include, SubdomainFu::Controller
|
7
|
+
|
8
|
+
RAILS_DEFAULT_LOGGER.info("** SubdomainFu: initialized properly")
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
begin
|
2
|
+
require File.dirname(__FILE__) + '/../../../../spec/spec_helper'
|
3
|
+
rescue LoadError
|
4
|
+
puts "You need to install rspec in your base app"
|
5
|
+
exit
|
6
|
+
end
|
7
|
+
|
8
|
+
plugin_spec_dir = File.dirname(__FILE__)
|
9
|
+
ActiveRecord::Base.logger = Logger.new(plugin_spec_dir + "/debug.log")
|
10
|
+
|
11
|
+
ActionController::Routing::Routes.draw do |map|
|
12
|
+
map.needs_subdomain '/needs_subdomain', :controller => "fu", :action => "awesome"
|
13
|
+
map.no_subdomain '/no_subdomain', :controller => "fu", :action => "lame"
|
14
|
+
map.needs_awesome '/needs_awesome', :controller => "fu", :action => "lame"
|
15
|
+
|
16
|
+
map.resources :foos do |fu|
|
17
|
+
fu.resources :bars
|
18
|
+
end
|
19
|
+
|
20
|
+
map.connect '/', :controller => "site", :action => "home", :conditions => {:subdomain => false}
|
21
|
+
map.connect '/', :controller => "app", :action => "home", :conditions => {:subdomain => true}
|
22
|
+
map.connect '/', :controller => "mobile", :action => "home", :conditions => {:subdomain => "m"}
|
23
|
+
|
24
|
+
map.connect '/subdomain_here', :controller => "app", :action => "success", :conditions => {:subdomain => true}
|
25
|
+
map.connect '/no_subdomain_here', :controller => "site", :action => "success", :conditions => {:subdomain => false}
|
26
|
+
map.connect '/m_subdomain_here', :controller => "mobile", :action => "success", :conditions => {:subdomain => "m"}
|
27
|
+
map.connect '/numbers_only_here', :controller => "numbers", :action => "success", :conditions => {:subdomain => /[0-9]+/}
|
28
|
+
|
29
|
+
map.connect '/:controller/:action/:id'
|
30
|
+
end
|
31
|
+
|
32
|
+
class Paramed
|
33
|
+
def initialize(param)
|
34
|
+
@param = param
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_param
|
38
|
+
@param || "param"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
include ActionController::UrlWriter
|
@@ -0,0 +1,217 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "SubdomainFu" do
|
4
|
+
before do
|
5
|
+
SubdomainFu.tld_sizes = SubdomainFu::DEFAULT_TLD_SIZES.dup
|
6
|
+
SubdomainFu.mirrors = SubdomainFu::DEFAULT_MIRRORS.dup
|
7
|
+
SubdomainFu.preferred_mirror = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "TLD Sizes" do
|
11
|
+
before do
|
12
|
+
SubdomainFu.tld_sizes = SubdomainFu::DEFAULT_TLD_SIZES.dup
|
13
|
+
end
|
14
|
+
|
15
|
+
it { SubdomainFu.tld_sizes.should be_kind_of(Hash) }
|
16
|
+
|
17
|
+
it "should have default values for development, test, and production" do
|
18
|
+
SubdomainFu.tld_sizes[:development].should == 0
|
19
|
+
SubdomainFu.tld_sizes[:test].should == 0
|
20
|
+
SubdomainFu.tld_sizes[:production].should == 1
|
21
|
+
end
|
22
|
+
|
23
|
+
it "#tld_size should be for the current environment" do
|
24
|
+
SubdomainFu.tld_size.should == SubdomainFu.tld_sizes[RAILS_ENV.to_sym]
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should be able to be set for the current environment" do
|
28
|
+
SubdomainFu.tld_size = 5
|
29
|
+
SubdomainFu.tld_size.should == 5
|
30
|
+
SubdomainFu.tld_sizes[:test].should == 5
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#has_subdomain?" do
|
35
|
+
it "should be true for non-mirrored subdomains" do
|
36
|
+
SubdomainFu.has_subdomain?("awesome").should be_true
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should be false for mirrored subdomains" do
|
40
|
+
SubdomainFu.has_subdomain?(SubdomainFu.mirrors.first).should be_false
|
41
|
+
end
|
42
|
+
|
43
|
+
it "shoud be false for a nil or blank subdomain" do
|
44
|
+
SubdomainFu.has_subdomain?("").should be_false
|
45
|
+
SubdomainFu.has_subdomain?(nil).should be_false
|
46
|
+
SubdomainFu.has_subdomain?(false).should be_false
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#subdomain_from" do
|
51
|
+
it "should return the subdomain based on the TLD of the current environment" do
|
52
|
+
SubdomainFu.subdomain_from("awesome.localhost").should == "awesome"
|
53
|
+
SubdomainFu.tld_size = 2
|
54
|
+
SubdomainFu.subdomain_from("awesome.localhost.co.uk").should == "awesome"
|
55
|
+
SubdomainFu.tld_size = 1
|
56
|
+
SubdomainFu.subdomain_from("awesome.localhost.com").should == "awesome"
|
57
|
+
SubdomainFu.tld_size = 0
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should join deep subdomains with a period" do
|
61
|
+
SubdomainFu.subdomain_from("awesome.coolguy.localhost").should == "awesome.coolguy"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should return nil for no subdomain" do
|
65
|
+
SubdomainFu.subdomain_from("localhost").should be_nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "#host_without_subdomain should chop of the subdomain and return the rest" do
|
70
|
+
SubdomainFu.host_without_subdomain("awesome.localhost:3000").should == "localhost:3000"
|
71
|
+
SubdomainFu.host_without_subdomain("something.awful.localhost:3000").should == "localhost:3000"
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "#preferred_mirror?" do
|
75
|
+
describe "when preferred_mirror is false" do
|
76
|
+
before do
|
77
|
+
SubdomainFu.preferred_mirror = false
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should return true for false" do
|
81
|
+
SubdomainFu.preferred_mirror?(false).should be_true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "#rewrite_host_for_subdomains" do
|
87
|
+
it "should not change the same subdomain" do
|
88
|
+
SubdomainFu.rewrite_host_for_subdomains("awesome","awesome.localhost").should == "awesome.localhost"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should not change an equivalent (mirrored) subdomain" do
|
92
|
+
SubdomainFu.rewrite_host_for_subdomains("www","localhost").should == "localhost"
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should change the subdomain if it's different" do
|
96
|
+
SubdomainFu.rewrite_host_for_subdomains("cool","www.localhost").should == "cool.localhost"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should remove the subdomain if passed false when it's not a mirror" do
|
100
|
+
SubdomainFu.rewrite_host_for_subdomains(false,"cool.localhost").should == "localhost"
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should not remove the subdomain if passed false when it is a mirror" do
|
104
|
+
SubdomainFu.rewrite_host_for_subdomains(false,"www.localhost").should == "www.localhost"
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should not remove the subdomain if passed nil when it's not a mirror" do
|
108
|
+
SubdomainFu.rewrite_host_for_subdomains(nil,"cool.localhost").should == "cool.localhost"
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "when preferred_mirror is false" do
|
112
|
+
before do
|
113
|
+
SubdomainFu.preferred_mirror = false
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should remove the subdomain if passed false when it is a mirror" do
|
117
|
+
SubdomainFu.rewrite_host_for_subdomains(false,"www.localhost").should == "localhost"
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should not remove the subdomain if passed nil when it's not a mirror" do
|
121
|
+
SubdomainFu.rewrite_host_for_subdomains(nil,"cool.localhost").should == "cool.localhost"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "#change_subdomain_of_host" do
|
127
|
+
it "should change it if passed a different one" do
|
128
|
+
SubdomainFu.change_subdomain_of_host("awesome","cool.localhost").should == "awesome.localhost"
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should remove it if passed nil" do
|
132
|
+
SubdomainFu.change_subdomain_of_host(nil,"cool.localhost").should == "localhost"
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should add it if there isn't one" do
|
136
|
+
SubdomainFu.change_subdomain_of_host("awesome","localhost").should == "awesome.localhost"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "#current_subdomain" do
|
141
|
+
it "should return the current subdomain if there is one" do
|
142
|
+
request = mock("request", :subdomains => ["awesome"])
|
143
|
+
SubdomainFu.current_subdomain(request).should == "awesome"
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should return nil if there's no subdomain" do
|
147
|
+
request = mock("request", :subdomains => [])
|
148
|
+
SubdomainFu.current_subdomain(request).should be_nil
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should return nil if the current subdomain is a mirror" do
|
152
|
+
request = mock("request", :subdomains => ["www"])
|
153
|
+
SubdomainFu.current_subdomain(request).should be_nil
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should return the whole thing (including a .) if there's multiple subdomains" do
|
157
|
+
request = mock("request", :subdomains => ["awesome","rad"])
|
158
|
+
SubdomainFu.current_subdomain(request).should == "awesome.rad"
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "#same_subdomain?" do
|
163
|
+
it { SubdomainFu.same_subdomain?("www","www.localhost").should be_true }
|
164
|
+
it { SubdomainFu.same_subdomain?("www","localhost").should be_true }
|
165
|
+
it { SubdomainFu.same_subdomain?("awesome","www.localhost").should be_false }
|
166
|
+
it { SubdomainFu.same_subdomain?("cool","awesome.localhost").should be_false }
|
167
|
+
it { SubdomainFu.same_subdomain?(nil,"www.localhost").should be_true }
|
168
|
+
it { SubdomainFu.same_subdomain?("www","awesome.localhost").should be_false }
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "#needs_rewrite?" do
|
172
|
+
it { SubdomainFu.needs_rewrite?("www","www.localhost").should be_false }
|
173
|
+
it { SubdomainFu.needs_rewrite?("www","localhost").should be_false }
|
174
|
+
it { SubdomainFu.needs_rewrite?("awesome","www.localhost").should be_true }
|
175
|
+
it { SubdomainFu.needs_rewrite?("cool","awesome.localhost").should be_true }
|
176
|
+
it { SubdomainFu.needs_rewrite?(nil,"www.localhost").should be_false }
|
177
|
+
it { SubdomainFu.needs_rewrite?(nil,"awesome.localhost").should be_false }
|
178
|
+
it { SubdomainFu.needs_rewrite?(false,"awesome.localhost").should be_true }
|
179
|
+
it { SubdomainFu.needs_rewrite?(false,"www.localhost").should be_false }
|
180
|
+
it { SubdomainFu.needs_rewrite?("www","awesome.localhost").should be_true }
|
181
|
+
|
182
|
+
describe "when preferred_mirror is false" do
|
183
|
+
before do
|
184
|
+
SubdomainFu.preferred_mirror = false
|
185
|
+
end
|
186
|
+
|
187
|
+
it { SubdomainFu.needs_rewrite?("www","www.localhost").should be_false }
|
188
|
+
it { SubdomainFu.needs_rewrite?("www","localhost").should be_false }
|
189
|
+
it { SubdomainFu.needs_rewrite?("awesome","www.localhost").should be_true }
|
190
|
+
it { SubdomainFu.needs_rewrite?("cool","awesome.localhost").should be_true }
|
191
|
+
it { SubdomainFu.needs_rewrite?(nil,"www.localhost").should be_false }
|
192
|
+
it { SubdomainFu.needs_rewrite?(nil,"awesome.localhost").should be_false }
|
193
|
+
it { SubdomainFu.needs_rewrite?(false,"awesome.localhost").should be_true }
|
194
|
+
#Only one different from default set of tests
|
195
|
+
it { SubdomainFu.needs_rewrite?(false,"www.localhost").should be_true }
|
196
|
+
it { SubdomainFu.needs_rewrite?("www","awesome.localhost").should be_true }
|
197
|
+
end
|
198
|
+
|
199
|
+
describe "when preferred_mirror is string" do
|
200
|
+
before do
|
201
|
+
SubdomainFu.preferred_mirror = "www"
|
202
|
+
end
|
203
|
+
|
204
|
+
it { SubdomainFu.needs_rewrite?("www","www.localhost").should be_false }
|
205
|
+
it { SubdomainFu.needs_rewrite?("awesome","www.localhost").should be_true }
|
206
|
+
# Following is different from default set of tests
|
207
|
+
it { SubdomainFu.needs_rewrite?("www","localhost").should be_true }
|
208
|
+
it { SubdomainFu.needs_rewrite?("cool","awesome.localhost").should be_true }
|
209
|
+
it { SubdomainFu.needs_rewrite?(nil,"www.localhost").should be_false }
|
210
|
+
it { SubdomainFu.needs_rewrite?(nil,"awesome.localhost").should be_false }
|
211
|
+
it { SubdomainFu.needs_rewrite?(false,"awesome.localhost").should be_true }
|
212
|
+
it { SubdomainFu.needs_rewrite?(false,"www.localhost").should be_false }
|
213
|
+
it { SubdomainFu.needs_rewrite?("www","awesome.localhost").should be_true }
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "SubdomainFu URL Writing" do
|
4
|
+
before do
|
5
|
+
SubdomainFu.tld_size = 1
|
6
|
+
SubdomainFu.mirrors = SubdomainFu::DEFAULT_MIRRORS.dup
|
7
|
+
SubdomainFu.override_only_path = true
|
8
|
+
SubdomainFu.preferred_mirror = nil
|
9
|
+
default_url_options[:host] = "example.com"
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#url_for" do
|
13
|
+
it "should be able to add a subdomain" do
|
14
|
+
url_for(:controller => "something", :action => "other", :subdomain => "awesome").should == "http://awesome.example.com/something/other"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be able to remove a subdomain" do
|
18
|
+
url_for(:controller => "something", :action => "other", :subdomain => false, :host => "awesome.example.com").should == "http://example.com/something/other"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should not change a mirrored subdomain" do
|
22
|
+
url_for(:controller => "something", :action => "other", :subdomain => false, :host => "www.example.com").should == "http://www.example.com/something/other"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should should not force the full url with :only_path if override_only_path is false (default)" do
|
26
|
+
SubdomainFu.override_only_path = false
|
27
|
+
url_for(:controller => "something", :action => "other", :subdomain => "awesome", :only_path => true).should == "/something/other"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should should force the full url, even with :only_path if override_only_path is true" do
|
31
|
+
SubdomainFu.override_only_path = true
|
32
|
+
url_for(:controller => "something", :action => "other", :subdomain => "awesome", :only_path => true).should == "http://awesome.example.com/something/other"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "Standard Routes" do
|
37
|
+
it "should be able to add a subdomain" do
|
38
|
+
needs_subdomain_url(:subdomain => "awesome").should == "http://awesome.example.com/needs_subdomain"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should be able to remove a subdomain" do
|
42
|
+
default_url_options[:host] = "awesome.example.com"
|
43
|
+
needs_subdomain_url(:subdomain => false).should == "http://example.com/needs_subdomain"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should not change a mirrored subdomain" do
|
47
|
+
default_url_options[:host] = "www.example.com"
|
48
|
+
needs_subdomain_url(:subdomain => false).should == "http://www.example.com/needs_subdomain"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should should force the full url, even with _path" do
|
52
|
+
needs_subdomain_path(:subdomain => "awesome").should == needs_subdomain_url(:subdomain => "awesome")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should not force the full url if it's the same as the current subdomain" do
|
56
|
+
default_url_options[:host] = "awesome.example.com"
|
57
|
+
needs_subdomain_path(:subdomain => "awesome").should == "/needs_subdomain"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should force the full url if it's a different subdomain" do
|
61
|
+
default_url_options[:host] = "awesome.example.com"
|
62
|
+
needs_subdomain_path(:subdomain => "crazy").should == "http://crazy.example.com/needs_subdomain"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should not force the full url if the current subdomain is nil and so is the target" do
|
66
|
+
needs_subdomain_path(:subdomain => nil).should == "/needs_subdomain"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should not force the full url if no :subdomain option is given" do
|
70
|
+
needs_subdomain_path.should == "/needs_subdomain"
|
71
|
+
default_url_options[:host] = "awesome.example.com"
|
72
|
+
needs_subdomain_path.should == "/needs_subdomain"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "Resourced Routes" do
|
77
|
+
it "should be able to add a subdomain" do
|
78
|
+
foo_path(:id => "something", :subdomain => "awesome").should == "http://awesome.example.com/foos/something"
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should be able to remove a subdomain" do
|
82
|
+
default_url_options[:host] = "awesome.example.com"
|
83
|
+
foo_path(:id => "something", :subdomain => false).should == "http://example.com/foos/something"
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should work when passed in a paramable object" do
|
87
|
+
foo_path(Paramed.new("something"), :subdomain => "awesome").should == "http://awesome.example.com/foos/something"
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should work when passed in a paramable object" do
|
91
|
+
foo_path(Paramed.new("something"), :subdomain => "awesome").should == "http://awesome.example.com/foos/something"
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should work when passed in a paramable object and no subdomain to a _path" do
|
95
|
+
default_url_options[:host] = "awesome.example.com"
|
96
|
+
foo_path(Paramed.new("something")).should == "/foos/something"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should work when passed in a paramable object and no subdomain to a _url" do
|
100
|
+
default_url_options[:host] = "awesome.example.com"
|
101
|
+
foo_url(Paramed.new("something")).should == "http://awesome.example.com/foos/something"
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should work on nested resource collections" do
|
105
|
+
foo_bars_path(Paramed.new("something"), :subdomain => "awesome").should == "http://awesome.example.com/foos/something/bars"
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should work on nested resource members" do
|
109
|
+
foo_bar_path(Paramed.new("something"),Paramed.new("else"), :subdomain => "awesome").should == "http://awesome.example.com/foos/something/bars/else"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "Preferred Mirror" do
|
114
|
+
before do
|
115
|
+
SubdomainFu.preferred_mirror = "www"
|
116
|
+
SubdomainFu.override_only_path = true
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should switch to the preferred mirror instead of no subdomain" do
|
120
|
+
default_url_options[:host] = "awesome.example.com"
|
121
|
+
needs_subdomain_url(:subdomain => false).should == "http://www.example.com/needs_subdomain"
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should switch to the preferred mirror automatically" do
|
125
|
+
default_url_options[:host] = "example.com"
|
126
|
+
needs_subdomain_url.should == "http://www.example.com/needs_subdomain"
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should work when passed in a paramable object and no subdomain to a _url" do
|
130
|
+
default_url_options[:host] = "awesome.example.com"
|
131
|
+
foo_url(Paramed.new("something")).should == "http://awesome.example.com/foos/something"
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should force a switch to no subdomain on a mirror if preferred_mirror is false" do
|
135
|
+
SubdomainFu.preferred_mirror = false
|
136
|
+
default_url_options[:host] = "www.example.com"
|
137
|
+
needs_subdomain_url(:subdomain => false).should == "http://example.com/needs_subdomain"
|
138
|
+
end
|
139
|
+
|
140
|
+
after do
|
141
|
+
SubdomainFu.preferred_mirror = nil
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
after do
|
146
|
+
SubdomainFu.tld_size = 0
|
147
|
+
default_url_options[:host] = "localhost"
|
148
|
+
end
|
149
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: subdomain-fu
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Michael Bleigh
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-31 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: SubdomainFu is a Rails plugin to provide all of the basic functionality necessary to handle multiple subdomain applications (such as Basecamp-esque subdomain accounts and more).
|
17
|
+
email: michael@intridea.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
files:
|
25
|
+
- CHANGELOG
|
26
|
+
- MIT-LICENSE
|
27
|
+
- README.rdoc
|
28
|
+
- Rakefile
|
29
|
+
- VERSION.yml
|
30
|
+
- lib/subdomain-fu.rb
|
31
|
+
- lib/subdomain_fu/routing_extensions.rb
|
32
|
+
- lib/subdomain_fu/url_rewriter.rb
|
33
|
+
- rails/init.rb
|
34
|
+
- spec/spec.opts
|
35
|
+
- spec/spec_helper.rb
|
36
|
+
- spec/subdomain_fu_spec.rb
|
37
|
+
- spec/url_rewriter_spec.rb
|
38
|
+
has_rdoc: true
|
39
|
+
homepage: http://github.com/mbleigh/subdomain-fu
|
40
|
+
licenses: []
|
41
|
+
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options:
|
44
|
+
- --charset=UTF-8
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.3.3
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: SubdomainFu is a Rails plugin that provides subdomain routing and URL writing helpers.
|
66
|
+
test_files:
|
67
|
+
- spec/spec_helper.rb
|
68
|
+
- spec/subdomain_fu_spec.rb
|
69
|
+
- spec/url_rewriter_spec.rb
|