diff options
Diffstat (limited to 'actionpack/lib/action_controller/url_rewriter.rb')
-rw-r--r-- | actionpack/lib/action_controller/url_rewriter.rb | 103 |
1 files changed, 90 insertions, 13 deletions
diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb index 3a38f23396..d86e2db67d 100644 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ b/actionpack/lib/action_controller/url_rewriter.rb @@ -1,19 +1,96 @@ module ActionController - # Write URLs from arbitrary places in your codebase, such as your mailers. + # In <b>routes.rb</b> one defines URL-to-controller mappings, but the reverse + # is also possible: an URL can be generated from one of your routing definitions. + # URL generation functionality is centralized in this module. # - # Example: + # See ActionController::Routing and ActionController::Resources for general + # information about routing and routes.rb. # - # class MyMailer - # include ActionController::UrlWriter - # default_url_options[:host] = 'www.basecamphq.com' + # <b>Tip:</b> If you need to generate URLs from your models or some other place, + # then ActionController::UrlWriter is what you're looking for. Read on for + # an introduction. # - # def signup_url(token) - # url_for(:controller => 'signup', action => 'index', :token => token) + # == URL generation from parameters + # + # As you may know, some functions - such as ActionController::Base#url_for + # and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set + # of parameters. For example, you've probably had the chance to write code + # like this in one of your views: + # + # <%= link_to('Click here', :controller => 'users', + # :action => 'new', :message => 'Welcome!') %> + # + # #=> Generates a link to: /users/new?message=Welcome%21 + # + # link_to, and all other functions that require URL generation functionality, + # actually use ActionController::UrlWriter under the hood. And in particular, + # they use the ActionController::UrlWriter#url_for method. One can generate + # the same path as the above example by using the following code: + # + # include UrlWriter + # url_for(:controller => 'users', + # :action => 'new', + # :message => 'Welcome!', + # :only_path => true) + # # => "/users/new?message=Welcome%21" + # + # Notice the <tt>:only_path => true</tt> part. This is because UrlWriter has no + # information about the website hostname that your Rails app is serving. So if you + # want to include the hostname as well, then you must also pass the <tt>:host</tt> + # argument: + # + # include UrlWriter + # url_for(:controller => 'users', + # :action => 'new', + # :message => 'Welcome!', + # :host => 'www.example.com') # Changed this. + # # => "http://www.example.com/users/new?message=Welcome%21" + # + # By default, all controllers and views have access to a special version of url_for, + # that already knows what the current hostname is. So if you use url_for in your + # controllers or your views, then you don't need to explicitly pass the <tt>:host</tt> + # argument. + # + # For convenience reasons, mailers provide a shortcut for ActionController::UrlWriter#url_for. + # So within mailers, you only have to type 'url_for' instead of 'ActionController::UrlWriter#url_for' + # in full. However, mailers don't have hostname information, and what's why you'll still + # have to specify the <tt>:host</tt> argument when generating URLs in mailers. + # + # + # == URL generation for named routes + # + # UrlWriter also allows one to access methods that have been auto-generated from + # named routes. For example, suppose that you have a 'users' resource in your + # <b>routes.rb</b>: + # + # map.resources :users + # + # This generates, among other things, the method <tt>users_path</tt>. By default, + # this method is accessible from your controllers, views and mailers. If you need + # to access this auto-generated method from other places (such as a model), then + # you can do that in two ways. + # + # The first way is to include ActionController::UrlWriter in your class: + # + # class User < ActiveRecord::Base + # include ActionController::UrlWriter # !!! + # + # def name=(value) + # write_attribute('name', value) + # write_attribute('base_uri', users_path) # !!! # end - # end + # end # - # In addition to providing +url_for+, named routes are also accessible after - # including UrlWriter. + # The second way is to access them through ActionController::UrlWriter. + # The autogenerated named routes methods are available as class methods: + # + # class User < ActiveRecord::Base + # def name=(value) + # write_attribute('name', value) + # path = ActionController::UrlWriter.users_path # !!! + # write_attribute('base_uri', path) # !!! + # end + # end module UrlWriter # The default options for urls written by this writer. Typically a <tt>:host</tt> # pair is provided. @@ -37,7 +114,7 @@ module ActionController # * <tt>:port</tt> - Optionally specify the port to connect to. # * <tt>:anchor</tt> - An anchor name to be appended to the path. # * <tt>:skip_relative_url_root</tt> - If true, the url is not constructed using the - # +relative_url_root+ set in ActionController::AbstractRequest.relative_url_root. + # +relative_url_root+ set in ActionController::Base.relative_url_root. # * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/" # # Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to @@ -67,7 +144,7 @@ module ActionController [:protocol, :host, :port, :skip_relative_url_root].each { |k| options.delete(k) } end trailing_slash = options.delete(:trailing_slash) if options.key?(:trailing_slash) - url << ActionController::AbstractRequest.relative_url_root.to_s unless options[:skip_relative_url_root] + url << ActionController::Base.relative_url_root.to_s unless options[:skip_relative_url_root] anchor = "##{CGI.escape options.delete(:anchor).to_param.to_s}" if options[:anchor] generated = Routing::Routes.generate(options, {}) url << (trailing_slash ? generated.sub(/\?|\z/) { "/" + $& } : generated) @@ -108,7 +185,7 @@ module ActionController end path = rewrite_path(options) - rewritten_url << @request.relative_url_root.to_s unless options[:skip_relative_url_root] + rewritten_url << ActionController::Base.relative_url_root.to_s unless options[:skip_relative_url_root] rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path) rewritten_url << "##{options[:anchor]}" if options[:anchor] |