Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 4814

Show
Ignore:
Timestamp:
08/24/06 06:15:01 (2 years ago)
Author:
ulysses
Message:

Add UrlWriter to allow writing urls from Mailers and scripts.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/actionpack/CHANGELOG

    r4807 r4814  
    11*SVN* 
     2 
     3* Add UrlWriter to allow writing urls from Mailers and scripts. [Nicholas Seckar] 
    24 
    35* Clean up and run the Active Record integration tests by default.  #5854 [kevin.clark@gmail.com, Jeremy Kemper] 
  • trunk/actionpack/lib/action_controller/url_rewriter.rb

    r4518 r4814  
    11module ActionController 
     2   
     3  # Write URLs from arbitrary places in your codebase, such as your mailers. 
     4  #  
     5  # Example: 
     6  #  
     7  #   class MyMailer 
     8  #     include ActionController::UrlWriter 
     9  #     default_url_options[:host] = 'www.basecamphq.com' 
     10  #      
     11  #     def signup_url(token) 
     12  #       url_for(:controller => 'signup', action => 'index', :token => token) 
     13  #     end 
     14  #  end 
     15  #  
     16  # In addition to providing +url_for+, named routes are also accessible after 
     17  # including UrlWriter. 
     18  #  
     19  module UrlWriter 
     20     
     21    # The default options for urls written by this writer. Typically a :host pair 
     22    # is provided. 
     23    mattr_accessor :default_url_options 
     24    self.default_url_options = {} 
     25     
     26    def self.included(base) #:nodoc: 
     27      ActionController::Routing::Routes.named_routes.install base 
     28      base.mattr_accessor :default_url_options 
     29      base.default_url_options ||= default_url_options 
     30    end 
     31     
     32    # Generate a url with the provided options. The following special options may 
     33    # effect the constructed url: 
     34    #  
     35    #   * :host Specifies the host the link should be targetted at. This option 
     36    #     must be provided either explicitly, or via default_url_options. 
     37    #   * :protocol The protocol to connect to. Defaults to 'http' 
     38    #   * :port Optionally specify the port to connect to. 
     39    #  
     40    def url_for(options) 
     41      options = self.class.default_url_options.merge(options) 
     42       
     43      raise "Missing host to link to! Please provide :host parameter or set default_url_options[:host]" unless options[:host] 
     44       
     45      url = '' 
     46      url << (options.delete(:protocol) || 'http') 
     47      url << '://' 
     48      url << options.delete(:host) 
     49      url << ":#{options.delete(:port)}" if options.key?(:port) 
     50      url << Routing::Routes.generate(options, {}) 
     51      return url 
     52    end 
     53     
     54  end 
     55   
    256  # Rewrites URLs for Base.redirect_to and Base.url_for in the controller. 
    3  
    457  class UrlRewriter #:nodoc: 
    558    RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :trailing_slash, :skip_relative_url_root] 
     
    47100      end 
    48101  end 
     102   
    49103end 
  • trunk/actionpack/test/controller/url_rewriter_test.rb

    r4394 r4814  
    2828    end 
    2929end 
     30 
     31class UrlWriterTests < Test::Unit::TestCase 
     32   
     33  class W 
     34    include ActionController::UrlWriter 
     35  end 
     36   
     37  def teardown 
     38    W.default_url_options.clear 
     39  end 
     40   
     41  def add_host! 
     42    W.default_url_options[:host] = 'www.basecamphq.com' 
     43  end 
     44   
     45  def test_exception_is_thrown_without_host 
     46    assert_raises RuntimeError do 
     47      W.new.url_for :controller => 'c', :action => 'a', :id => 'i' 
     48    end 
     49  end 
     50   
     51  def test_default_host 
     52    add_host! 
     53    assert_equal('http://www.basecamphq.com/c/a/i', 
     54      W.new.url_for(:controller => 'c', :action => 'a', :id => 'i') 
     55    ) 
     56  end 
     57   
     58  def test_host_may_be_overridden 
     59    add_host! 
     60    assert_equal('http://37signals.basecamphq.com/c/a/i', 
     61      W.new.url_for(:host => '37signals.basecamphq.com', :controller => 'c', :action => 'a', :id => 'i') 
     62    ) 
     63  end 
     64   
     65  def test_port 
     66    add_host! 
     67    assert_equal('http://www.basecamphq.com:3000/c/a/i', 
     68      W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :port => 3000) 
     69    ) 
     70  end 
     71   
     72  def test_protocol 
     73    add_host! 
     74    assert_equal('https://www.basecamphq.com/c/a/i', 
     75      W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https') 
     76    ) 
     77  end 
     78   
     79  def test_named_route 
     80    ActionController::Routing::Routes.draw do |map| 
     81      map.home '/home/sweet/home/:user' 
     82      map.connect ':controller/:action/:id' 
     83    end 
     84     
     85    # We need to create a new class in order to install the new named route. 
     86    kls = Class.new { include ActionController::UrlWriter } 
     87    assert kls.new.respond_to?(:home_url) 
     88    assert_equal 'http://www.basecamphq.com/home/sweet/home/again', 
     89      kls.new.send(:home_url, :host => 'www.basecamphq.com', :user => 'again') 
     90  ensure 
     91    ActionController::Routing::Routes.load! 
     92  end 
     93   
     94end