Site dispatcher in its core version works + tests are coming
This commit is contained in:
parent
3b8a6c67df
commit
8d1f6a24e1
7
app/controllers/home_controller.rb
Normal file
7
app/controllers/home_controller.rb
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class HomeController < ActionController::Base
|
||||||
|
|
||||||
|
def show; end
|
||||||
|
|
||||||
|
def unknown; end
|
||||||
|
|
||||||
|
end
|
9
app/controllers/pages_controller.rb
Normal file
9
app/controllers/pages_controller.rb
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
class PagesController < ActionController::Base
|
||||||
|
|
||||||
|
include Locomotive::Routing::SiteDispatcher
|
||||||
|
|
||||||
|
before_filter :require_site
|
||||||
|
|
||||||
|
def show; end
|
||||||
|
|
||||||
|
end
|
@ -10,7 +10,7 @@ class Site
|
|||||||
## validations ##
|
## validations ##
|
||||||
validates_presence_of :name, :subdomain
|
validates_presence_of :name, :subdomain
|
||||||
validates_uniqueness_of :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
|
validates_format_of :subdomain, :with => Locomotive::Regexps::SUBDOMAIN, :allow_blank => true
|
||||||
validate :domains_must_be_valid_and_unique
|
validate :domains_must_be_valid_and_unique
|
||||||
|
|
||||||
@ -28,11 +28,11 @@ class Site
|
|||||||
|
|
||||||
def add_subdomain_to_domains
|
def add_subdomain_to_domains
|
||||||
self.domains ||= []
|
self.domains ||= []
|
||||||
(self.domains << "#{self.subdomain}.#{Locomotive::Configuration.default_domain}").uniq!
|
(self.domains << "#{self.subdomain}.#{Locomotive.config.default_domain}").uniq!
|
||||||
end
|
end
|
||||||
|
|
||||||
def domains_without_subdomain
|
def domains_without_subdomain
|
||||||
(self.domains || []) - ["#{self.subdomain}.#{Locomotive::Configuration.default_domain}"]
|
(self.domains || []) - ["#{self.subdomain}.#{Locomotive.config.default_domain}"]
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
3
app/views/home/show.html.erb
Normal file
3
app/views/home/show.html.erb
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<h1>Locomotive rocks !!!</h1>
|
||||||
|
|
||||||
|
<p><%= flash[:error] %></p>
|
8
app/views/pages/show.html.erb
Normal file
8
app/views/pages/show.html.erb
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title><%= current_site.name %></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>...rendering liquid templates soon</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,3 +1,5 @@
|
|||||||
Locomotive::Configuration.setup do |config|
|
require 'lib/locomotive.rb'
|
||||||
|
|
||||||
|
Locomotive.configure do |config|
|
||||||
config.default_domain = 'example.com'
|
config.default_domain = 'example.com'
|
||||||
end
|
end
|
@ -1,60 +1,8 @@
|
|||||||
Locomotive::Application.routes.draw do |map|
|
Locomotive::Application.routes.draw do |map|
|
||||||
# de#vise_for :accounts
|
|
||||||
|
|
||||||
# The priority is based upon order of creation:
|
constraints(Locomotive::Routing::DefaultConstraint) do
|
||||||
# first created -> highest priority.
|
root :to => 'home#show'
|
||||||
|
end
|
||||||
|
|
||||||
# Sample of regular route:
|
match '/' => 'pages#show'
|
||||||
# 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)))'
|
|
||||||
end
|
end
|
||||||
|
@ -5,3 +5,6 @@
|
|||||||
#
|
#
|
||||||
# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
|
# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
|
||||||
# Mayor.create(:name => 'Daley', :city => cities.first)
|
# Mayor.create(:name => 'Daley', :city => cities.first)
|
||||||
|
|
||||||
|
|
||||||
|
Site.create! :name => 'Locomotive test website', :subdomain => 'test'
|
79
lib/locomotive.rb
Normal file
79
lib/locomotive.rb
Normal file
@ -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
|
@ -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
|
|
45
lib/locomotive/routing/default_constraint.rb
Normal file
45
lib/locomotive/routing/default_constraint.rb
Normal file
@ -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
|
43
lib/locomotive/routing/site_dispatcher.rb
Normal file
43
lib/locomotive/routing/site_dispatcher.rb
Normal file
@ -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
|
@ -1,278 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Ruby on Rails: Welcome aboard</title>
|
|
||||||
<style type="text/css" media="screen">
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
margin-bottom: 25px;
|
|
||||||
padding: 0;
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
font-family: "Lucida Grande", "Bitstream Vera Sans", "Verdana";
|
|
||||||
font-size: 13px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 28px;
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {color: #03c}
|
|
||||||
a:hover {
|
|
||||||
background-color: #03c;
|
|
||||||
color: white;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#page {
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
width: 750px;
|
|
||||||
margin: 0;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
#content {
|
|
||||||
float: left;
|
|
||||||
background-color: white;
|
|
||||||
border: 3px solid #aaa;
|
|
||||||
border-top: none;
|
|
||||||
padding: 25px;
|
|
||||||
width: 500px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#sidebar {
|
|
||||||
float: right;
|
|
||||||
width: 175px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#footer {
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#header, #about, #getting-started {
|
|
||||||
padding-left: 75px;
|
|
||||||
padding-right: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#header {
|
|
||||||
background-image: url("images/rails.png");
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: top left;
|
|
||||||
height: 64px;
|
|
||||||
}
|
|
||||||
#header h1, #header h2 {margin: 0}
|
|
||||||
#header h2 {
|
|
||||||
color: #888;
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#about h3 {
|
|
||||||
margin: 0;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#about-content {
|
|
||||||
background-color: #ffd;
|
|
||||||
border: 1px solid #fc0;
|
|
||||||
margin-left: -11px;
|
|
||||||
}
|
|
||||||
#about-content table {
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
font-size: 11px;
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
#about-content td {
|
|
||||||
padding: 10px;
|
|
||||||
padding-top: 3px;
|
|
||||||
padding-bottom: 3px;
|
|
||||||
}
|
|
||||||
#about-content td.name {color: #555}
|
|
||||||
#about-content td.value {color: #000}
|
|
||||||
|
|
||||||
#about-content ul {
|
|
||||||
padding: 0;
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#about-content.failure {
|
|
||||||
background-color: #fcc;
|
|
||||||
border: 1px solid #f00;
|
|
||||||
}
|
|
||||||
#about-content.failure p {
|
|
||||||
margin: 0;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#getting-started {
|
|
||||||
border-top: 1px solid #ccc;
|
|
||||||
margin-top: 25px;
|
|
||||||
padding-top: 15px;
|
|
||||||
}
|
|
||||||
#getting-started h1 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
#getting-started h2 {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: normal;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 25px;
|
|
||||||
}
|
|
||||||
#getting-started ol {
|
|
||||||
margin-left: 0;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
#getting-started li {
|
|
||||||
font-size: 18px;
|
|
||||||
color: #888;
|
|
||||||
margin-bottom: 25px;
|
|
||||||
}
|
|
||||||
#getting-started li h2 {
|
|
||||||
margin: 0;
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: 18px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
#getting-started li p {
|
|
||||||
color: #555;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#search {
|
|
||||||
margin: 0;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
font-size: 11px;
|
|
||||||
}
|
|
||||||
#search input {
|
|
||||||
font-size: 11px;
|
|
||||||
margin: 2px;
|
|
||||||
}
|
|
||||||
#search-text {width: 170px}
|
|
||||||
|
|
||||||
|
|
||||||
#sidebar ul {
|
|
||||||
margin-left: 0;
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
#sidebar ul h3 {
|
|
||||||
margin-top: 25px;
|
|
||||||
font-size: 16px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
border-bottom: 1px solid #ccc;
|
|
||||||
}
|
|
||||||
#sidebar li {
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
#sidebar ul.links li {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
<script type="text/javascript" src="javascripts/prototype.js"></script>
|
|
||||||
<script type="text/javascript" src="javascripts/effects.js"></script>
|
|
||||||
<script type="text/javascript">
|
|
||||||
function about() {
|
|
||||||
if (Element.empty('about-content')) {
|
|
||||||
new Ajax.Updater('about-content', 'rails/info/properties', {
|
|
||||||
method: 'get',
|
|
||||||
onFailure: function() {Element.classNames('about-content').add('failure')},
|
|
||||||
onComplete: function() {new Effect.BlindDown('about-content', {duration: 0.25})}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
new Effect[Element.visible('about-content') ?
|
|
||||||
'BlindUp' : 'BlindDown']('about-content', {duration: 0.25});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.onload = function() {
|
|
||||||
$('search-text').value = '';
|
|
||||||
$('search').onsubmit = function() {
|
|
||||||
$('search-text').value = 'site:rubyonrails.org ' + $F('search-text');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="page">
|
|
||||||
<div id="sidebar">
|
|
||||||
<ul id="sidebar-items">
|
|
||||||
<li>
|
|
||||||
<form id="search" action="http://www.google.com/search" method="get">
|
|
||||||
<input type="hidden" name="hl" value="en" />
|
|
||||||
<input type="text" id="search-text" name="q" value="site:rubyonrails.org " />
|
|
||||||
<input type="submit" value="Search" /> the Rails site
|
|
||||||
</form>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<h3>Join the community</h3>
|
|
||||||
<ul class="links">
|
|
||||||
<li><a href="http://www.rubyonrails.org/">Ruby on Rails</a></li>
|
|
||||||
<li><a href="http://weblog.rubyonrails.org/">Official weblog</a></li>
|
|
||||||
<li><a href="http://wiki.rubyonrails.org/">Wiki</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<h3>Browse the documentation</h3>
|
|
||||||
<ul class="links">
|
|
||||||
<li><a href="http://api.rubyonrails.org/">Rails API</a></li>
|
|
||||||
<li><a href="http://stdlib.rubyonrails.org/">Ruby standard library</a></li>
|
|
||||||
<li><a href="http://corelib.rubyonrails.org/">Ruby core</a></li>
|
|
||||||
<li><a href="http://guides.rubyonrails.org/">Rails Guides</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="content">
|
|
||||||
<div id="header">
|
|
||||||
<h1>Welcome aboard</h1>
|
|
||||||
<h2>You’re riding Ruby on Rails!</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="about">
|
|
||||||
<h3><a href="rails/info/properties" onclick="about(); return false">About your application’s environment</a></h3>
|
|
||||||
<div id="about-content" style="display: none"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="getting-started">
|
|
||||||
<h1>Getting started</h1>
|
|
||||||
<h2>Here’s how to get rolling:</h2>
|
|
||||||
|
|
||||||
<ol>
|
|
||||||
<li>
|
|
||||||
<h2>Use <code>rails generate</code> to create your models and controllers</h2>
|
|
||||||
<p>To see all available options, run it without parameters.</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<h2>Set up a default route and remove or rename this file</h2>
|
|
||||||
<p>Routes are set up in config/routes.rb.</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<h2>Create your database</h2>
|
|
||||||
<p>Run <code>rake db:migrate</code> to create your database. If you're not using SQLite (the default), edit <code>config/database.yml</code> with your username and password.</p>
|
|
||||||
</li>
|
|
||||||
</ol>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="footer"> </div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue
Block a user