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:

- -
    -
  1. -

    Use rails generate to create your models and controllers

    -

    To see all available options, run it without parameters.

    -
  2. - -
  3. -

    Set up a default route and remove or rename this file

    -

    Routes are set up in config/routes.rb.

    -
  4. - -
  5. -

    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.

    -
  6. -
-
-
- - -
- -