diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb
new file mode 100644
index 00000000..6d87a41c
--- /dev/null
+++ b/app/controllers/home_controller.rb
@@ -0,0 +1,7 @@
+class HomeController < ActionController::Base
+
+ def show; end
+
+ def unknown; end
+
+end
\ No newline at end of file
diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb
new file mode 100644
index 00000000..3d3ec4d1
--- /dev/null
+++ b/app/controllers/pages_controller.rb
@@ -0,0 +1,9 @@
+class PagesController < ActionController::Base
+
+ include Locomotive::Routing::SiteDispatcher
+
+ before_filter :require_site
+
+ def show; end
+
+end
\ No newline at end of file
diff --git a/app/models/site.rb b/app/models/site.rb
index e6838e6f..a9361723 100644
--- a/app/models/site.rb
+++ b/app/models/site.rb
@@ -10,7 +10,7 @@ class Site
## validations ##
validates_presence_of :name, :subdomain
validates_uniqueness_of :subdomain
- validates_exclusion_of :subdomain, :in => Locomotive::Configuration.forbidden_subdomains
+ validates_exclusion_of :subdomain, :in => Locomotive.config.reserved_subdomains
validates_format_of :subdomain, :with => Locomotive::Regexps::SUBDOMAIN, :allow_blank => true
validate :domains_must_be_valid_and_unique
@@ -28,11 +28,11 @@ class Site
def add_subdomain_to_domains
self.domains ||= []
- (self.domains << "#{self.subdomain}.#{Locomotive::Configuration.default_domain}").uniq!
+ (self.domains << "#{self.subdomain}.#{Locomotive.config.default_domain}").uniq!
end
def domains_without_subdomain
- (self.domains || []) - ["#{self.subdomain}.#{Locomotive::Configuration.default_domain}"]
+ (self.domains || []) - ["#{self.subdomain}.#{Locomotive.config.default_domain}"]
end
protected
diff --git a/app/views/home/show.html.erb b/app/views/home/show.html.erb
new file mode 100644
index 00000000..3261094a
--- /dev/null
+++ b/app/views/home/show.html.erb
@@ -0,0 +1,3 @@
+
Locomotive rocks !!!
+
+<%= flash[:error] %>
\ No newline at end of file
diff --git a/app/views/pages/show.html.erb b/app/views/pages/show.html.erb
new file mode 100644
index 00000000..5d382f44
--- /dev/null
+++ b/app/views/pages/show.html.erb
@@ -0,0 +1,8 @@
+
+
+ <%= current_site.name %>
+
+
+ ...rendering liquid templates soon
+
+
\ No newline at end of file
diff --git a/config/initializers/locomotive.rb b/config/initializers/locomotive.rb
index 2f118f1c..b02ad88d 100644
--- a/config/initializers/locomotive.rb
+++ b/config/initializers/locomotive.rb
@@ -1,3 +1,5 @@
-Locomotive::Configuration.setup do |config|
+require 'lib/locomotive.rb'
+
+Locomotive.configure do |config|
config.default_domain = 'example.com'
end
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index a80880ba..34cb5584 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,60 +1,8 @@
Locomotive::Application.routes.draw do |map|
- # de#vise_for :accounts
-
- # The priority is based upon order of creation:
- # first created -> highest priority.
-
- # Sample of regular route:
- # match 'products/:id' => 'catalog#view'
- # Keep in mind you can assign values other than :controller and :action
-
- # Sample of named route:
- # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
- # This route can be invoked with purchase_url(:id => product.id)
-
- # Sample resource route (maps HTTP verbs to controller actions automatically):
- # resources :products
-
- # Sample resource route with options:
- # resources :products do
- # member do
- # get :short
- # post :toggle
- # end
- #
- # collection do
- # get :sold
- # end
- # end
-
- # Sample resource route with sub-resources:
- # resources :products do
- # resources :comments, :sales
- # resource :seller
- # end
-
- # Sample resource route with more complex sub-resources
- # resources :products do
- # resources :comments
- # resources :sales do
- # get :recent, :on => :collection
- # end
- # end
-
- # Sample resource route within a namespace:
- # namespace :admin do
- # # Directs /admin/products/* to Admin::ProductsController
- # # (app/controllers/admin/products_controller.rb)
- # resources :products
- # end
-
- # You can have the root of your site routed with "root"
- # just remember to delete public/index.html.
- # root :to => "welcome#index"
-
- # See how all your routes lay out with "rake routes"
-
- # This is a legacy wild controller route that's not recommended for RESTful applications.
- # Note: This route will make all actions in every controller accessible via GET requests.
- # match ':controller(/:action(/:id(.:format)))'
+
+ constraints(Locomotive::Routing::DefaultConstraint) do
+ root :to => 'home#show'
+ end
+
+ match '/' => 'pages#show'
end
diff --git a/db/seeds.rb b/db/seeds.rb
index 664d8c74..3c45d823 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -5,3 +5,6 @@
#
# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
# Mayor.create(:name => 'Daley', :city => cities.first)
+
+
+Site.create! :name => 'Locomotive test website', :subdomain => 'test'
\ No newline at end of file
diff --git a/lib/locomotive.rb b/lib/locomotive.rb
new file mode 100644
index 00000000..22b6a6ea
--- /dev/null
+++ b/lib/locomotive.rb
@@ -0,0 +1,79 @@
+module Locomotive
+
+ class << self
+ attr_accessor :config
+
+ def config
+ self.config = Configuration.new unless @config
+ @config
+ end
+ end
+
+ def self.configure
+ self.config ||= Configuration.new
+ yield(self.config)
+ end
+
+ class Configuration
+
+ @@defaults = {
+ :default_domain => 'rails.local.fr',
+ :reserved_subdomains => %w{www admin email blog webmail mail support help site sites}
+ }
+
+ cattr_accessor :settings
+
+ def initialize
+ @@settings = self.class.get_from_hash(@@defaults)
+ end
+
+ def self.settings
+ @@settings
+ end
+
+ def method_missing(name, *args, &block)
+ self.settings.send(name, *args, &block)
+ end
+
+ protected
+
+ # converts a hash map into a ConfigurationHash
+ def self.get_from_hash(hash)
+ config = ConfigurationHash.new
+
+ hash.each_pair do |key, value|
+ config[key] = value.is_a?(Hash) ? self.get_from_hash(value) : value
+ end
+
+ config
+ end
+ end
+
+ # specialized hash for storing configuration settings
+ class ConfigurationHash < Hash
+ # ensure that default entries always produce
+ # instances of the ConfigurationHash class
+ def default(key=nil)
+ include?(key) ? self[key] : self[key] = self.class.new
+ end
+
+ # retrieves the specified key and yields it
+ # if a block is provided
+ def [](key, &block)
+ block_given? ? yield(super(key)) : super(key)
+ end
+
+ # provides member-based access to keys
+ # i.e. params.id === params[:id]
+ # note: all keys are converted to symbols
+ def method_missing(name, *args, &block)
+ if name.to_s.ends_with? '='
+ send :[]=, name.to_s.chomp('=').to_sym, *args
+ else
+ send(:[], name.to_sym, &block)
+ end
+ end
+ end
+
+
+end
\ No newline at end of file
diff --git a/lib/locomotive/configuration.rb b/lib/locomotive/configuration.rb
deleted file mode 100644
index 3fce4e78..00000000
--- a/lib/locomotive/configuration.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-# require 'active_support'
-
-# Custom configuration settings
-# code inspired by http://slateinfo.blogs.wvu.edu/
-#
-# Example:
-# Locomotive::Configuration.setup do |config|
-# config.title = "Hello world !!!"
-#
-# config.admin do |admin|
-# admin.per_page 10
-# end
-# end
-#
-# Locomotive::Configuration.admin.per_page # => "10"
-#
-# # some alternate ways to access the settings
-# Locomotive::Configuration.config[:admin][:per_page] # => "10"
-
-module Locomotive
-
- class Configuration
-
- DEFAULT_SETTINGS = {
- :default_domain => 'localhost',
- :forbidden_subdomains => %w{www admin email blog webmail mail support help site sites}
- }
-
- cattr_accessor :settings
-
- # creates a new configuration object if
- # necessary
- def self.settings # !> redefine settings
- if @@settings.nil?
- @@settings = self.get_from_hash(DEFAULT_SETTINGS)
- else
- @@settings
- end
- end
-
- def self.setup
- block_given? ? yield(self.settings) : self.settings
- end
-
- # reset settings
- def self.reset
- @@settings = nil
- end
-
- # returns the current configuration
- # by passing a block you can easily edit the
- # configuration values
- def self.config
- block_given? ? yield(self.settings) : self.settings
- end
-
- def self.method_missing(name, *args, &block)
- self.config.send(name, *args, &block)
- end
-
- protected
-
- # converts a hash map into a ConfigurationHash
- def self.get_from_hash(hash)
- config = ConfigurationHash.new
-
- hash.each_pair do |key, value|
- config[key] = value.is_a?(Hash) ? self.get_from_hash(value) : value
- end
-
- config
- end
- end
-
- # specialized hash for storing configuration settings
- class ConfigurationHash < Hash
- # ensure that default entries always produce
- # instances of the ConfigurationHash class
- def default(key=nil)
- include?(key) ? self[key] : self[key] = self.class.new
- end
-
- # retrieves the specified key and yields it
- # if a block is provided
- def [](key, &block)
- block_given? ? yield(super(key)) : super(key)
- end
-
- # provides member-based access to keys
- # i.e. params.id === params[:id]
- # note: all keys are converted to symbols
- def method_missing(name, *args, &block)
- if name.to_s.ends_with? '='
- send :[]=, name.to_s.chomp('=').to_sym, *args
- else
- send(:[], name.to_sym, &block)
- end
- end
- end
-end
diff --git a/lib/locomotive/routing/default_constraint.rb b/lib/locomotive/routing/default_constraint.rb
new file mode 100644
index 00000000..ac741aca
--- /dev/null
+++ b/lib/locomotive/routing/default_constraint.rb
@@ -0,0 +1,45 @@
+module Locomotive
+
+ module Routing
+
+ class DefaultConstraint
+
+ def self.matches?(request)
+ domain, subdomain = domain_and_subdomain(request)
+ subdomain = 'www' if subdomain.blank?
+
+ # puts "domain = #{domain} / #{Locomotive.config.default_domain.inspect}"
+ # puts "subdomain = #{subdomain} / #{Locomotive.config.reserved_subdomains.inspect}"
+
+ domain == Locomotive.config.default_domain && Locomotive.config.reserved_subdomains.include?(subdomain)
+ end
+
+ # see actionpack/lib/action_dispatch/http/url.rb for more information
+ def self.domain_and_subdomain(request)
+ subdomain = extract_subdomain(request)
+ [extract_domain(request), extract_subdomain(request)]
+ end
+
+ def self.extract_domain(request, tld_length = 1)
+ return nil unless named_host?(request.host)
+ request.host.split('.').last(1 + tld_length).join('.')
+ end
+
+ def self.extract_subdomain(request, tld_length = 1)
+ subdomains(request, tld_length).join('.')
+ end
+
+ def self.named_host?(host)
+ !(host.nil? || /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.match(host))
+ end
+
+ def self.subdomains(request, tld_length = 1)
+ return [] unless named_host?(request.host)
+ parts = request.host.split('.')
+ parts[0..-(tld_length+2)]
+ end
+ end
+
+ end
+
+end
\ No newline at end of file
diff --git a/lib/locomotive/routing/site_dispatcher.rb b/lib/locomotive/routing/site_dispatcher.rb
new file mode 100644
index 00000000..91222665
--- /dev/null
+++ b/lib/locomotive/routing/site_dispatcher.rb
@@ -0,0 +1,43 @@
+module Locomotive
+
+ module Routing
+
+ module SiteDispatcher
+
+ def self.included(base)
+ base.class_eval do
+ include Locomotive::Routing::SiteDispatcher::InstanceMethods
+
+ before_filter :fetch_site
+
+ helper_method :current_site
+ end
+ end
+
+ module InstanceMethods
+
+ protected
+
+ def fetch_site
+ @site = Site.match_domain(request.host).first
+ end
+
+ def current_site
+ @site ||= fetch_site
+ end
+
+ def require_site
+ redirect_to application_root_url and return false if current_site.nil?
+ end
+
+ def application_root_url
+ root_url(:host => Locomotive.config.default_domain, :port => request.port)
+ end
+
+ end
+
+ end
+
+ end
+
+end
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
deleted file mode 100644
index ef916f9c..00000000
--- a/public/index.html
+++ /dev/null
@@ -1,278 +0,0 @@
-
-
-
- Ruby on Rails: Welcome aboard
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Getting started
-
Here’s how to get rolling:
-
-
- -
-
Use rails generate
to create your models and controllers
- To see all available options, run it without parameters.
-
-
- -
-
Set up a default route and remove or rename this file
- Routes are set up in config/routes.rb.
-
-
- -
-
Create your database
- Run rake db:migrate
to create your database. If you're not using SQLite (the default), edit config/database.yml
with your username and password.
-
-
-
-
-
-
-
-
-