module ActionView::Helpers::UrlHelper

def add_confirm_to_attributes!(html_options, confirm)

def add_confirm_to_attributes!(html_options, confirm)
  html_options["data-confirm"] = confirm if confirm
end

def add_method_to_attributes!(html_options, method)

def add_method_to_attributes!(html_options, method)
  html_options["rel"] = "nofollow" if method && method.to_s.downcase != "get"
  html_options["data-method"] = method if method
end

def array_or_string_for_javascript(option)

def array_or_string_for_javascript(option)
  if option.kind_of?(Array)
    "['#{option.join('\',\'')}']"
  elsif !option.nil?
    "'#{option}'"
  end
end

def button_to(name, options = {}, html_options = {})

#
# "
#

#
#
#

# => "

:method => "delete", :remote => true, :disable_with => 'loading...') %>
<%= button_to('Destroy', 'http://www.example.com', :confirm => 'Are you sure?',


#
"
#

#
#
#

# => "

:confirm => "Are you sure?", :method => :delete %>
<%= button_to "Delete Image", { :action => "delete", :id => @image.id },


#
"
#

# => "

<%= button_to "New", :action => "new" %>
==== Examples

submit behaviour. By default this behaviour is an ajax submit.
* :remote - If set to true, will allow the Unobtrusive JavaScript drivers to control the
processed normally, otherwise no action is taken.
prompt with the question specified. If the user accepts, the link is
* :confirm - This will use the unobtrusive JavaScript driver to
* :disabled - Specifies the anchor name to be appended to the path.
* :method - Specifies the anchor name to be appended to the path.
There are a few special +html_options+:

The +options+ hash accepts the same options as url_for.
==== Options

to change the HTTP verb used to submit the form.
If you are using RESTful routes, you can pass the :method
disable the button by passing :disabled => true in +html_options+.
is given, it will default to performing a POST operation. You can also
described in the +link_to+ documentation. If no :method modifier
This method accepts the :method and :confirm modifiers
the form submission and input element behavior using +html_options+.
to allow styling of the form itself and its children. You can control
The generated form element has a class name of button_to

the +link_to+ documentation.
using the +link_to+ method with the :method modifier as described in
If the HTML button does not work with your layout, you can also consider
cause changes to your data are not triggered by search bots or accelerators.
by the set of +options+. This is the safest method to ensure links that
Generates a form containing a single button that submits to the URL created
def button_to(name, options = {}, html_options = {})
  html_options = html_options.stringify_keys
  convert_boolean_attributes!(html_options, %w( disabled ))
  method_tag = ''
  if (method = html_options.delete('method')) && %w{put delete}.include?(method.to_s)
    method_tag = tag('input', :type => 'hidden', :name => '_method', :value => method.to_s)
  end
  form_method = method.to_s == 'get' ? 'get' : 'post'
  remote = html_options.delete('remote')
  request_token_tag = ''
  if form_method == 'post' && protect_against_forgery?
    request_token_tag = tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
  end
  url = options.is_a?(String) ? options : self.url_for(options)
  name ||= url
  html_options = convert_options_to_data_attributes(options, html_options)
  html_options.merge!("type" => "submit", "value" => name)
  ("<form method=\"#{form_method}\" action=\"#{html_escape(url)}\" #{"data-remote=\"true\"" if remote} class=\"button_to\"><div>" +
    method_tag + tag("input", html_options) + request_token_tag + "</div></form>").html_safe
end

def convert_boolean_attributes!(html_options, bool_attrs)

%w( checked disabled readonly ) )
convert_boolean_attributes!( html_options,

Example:

in place.
Returns the updated +html_options+ hash, which is also modified

http://www.w3.org/TR/xhtml1/#h-4.5)
section 4.5 "Attribute Minimization" for more:
removed from the +html_options+ hash. (See the XHTML 1.0 spec,
replaced with the attribute's name; otherwise the attribute is
if the associated +bool_value+ evaluates to true, it is

"attr" => bool_value

given as:
More specifically, for each boolean attribute in +html_options+

its name is listed in the given +bool_attrs+ array.)
HTML/XHTML. (An attribute is considered to be boolean if
attributes from true/false form into the form required by
Processes the +html_options+ hash, converting the boolean
def convert_boolean_attributes!(html_options, bool_attrs)
  bool_attrs.each { |x| html_options[x] = x if html_options.delete(x) }
  html_options
end

def convert_options_to_data_attributes(options, html_options)

def convert_options_to_data_attributes(options, html_options)
  html_options = {} if html_options.nil?
  html_options = html_options.stringify_keys
  if (options.is_a?(Hash) && options.key?('remote') && options.delete('remote')) || (html_options.is_a?(Hash) && html_options.key?('remote') && html_options.delete('remote'))
    html_options['data-remote'] = 'true'
  end
  confirm = html_options.delete("confirm")
  if html_options.key?("popup")
    ActiveSupport::Deprecation.warn(":popup has been deprecated", caller)
  end
  method, href = html_options.delete("method"), html_options['href']
  add_confirm_to_attributes!(html_options, confirm) if confirm
  add_method_to_attributes!(html_options, method)   if method
  html_options
end

def current_page?(options)

# => false
current_page?(:controller => 'library', :action => 'checkout')

# => true
current_page?(:action => 'checkout')

# => false
current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc')

# => false
current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc', :page=>'2')

# => true
current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc', :page=>'1')

# => true
current_page?(:controller => 'shop', :action => 'checkout')

# => false
current_page?(:action => 'process')

Let's say we're in the /shop/checkout?order=desc&page=1 action.

# => false
current_page?(:controller => 'library', :action => 'checkout')

# => true
current_page?(:action => 'checkout')

# => false
current_page?(:controller => 'shop', :action => 'checkout', :order => 'asc')

# => true
current_page?(:controller => 'shop', :action => 'checkout')

# => false
current_page?(:action => 'process')

Let's say we're in the /shop/checkout?order=desc action.
==== Examples

True if the current request URI was generated by the given +options+.
def current_page?(options)
  unless request
    raise "You cannot use helpers that need to determine the current " \
          "page unless your view context provides a Request object " \
          "in a #request method"
  end
  url_string = url_for(options)
  # We ignore any extra parameters in the request_uri if the
  # submitted url doesn't have any either.  This lets the function
  # work with things like ?order=asc
  if url_string.index("?")
    request_uri = request.fullpath
  else
    request_uri = request.path
  end
  if url_string =~ /^\w+:\/\//
    url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}"
  else
    url_string == request_uri
  end
end

def link_to(*args, &block)

# => Destroy
link_to("Destroy", "http://www.example.com", :method => :delete, :confirm => "Are you sure?")

# => Visit Other Site
link_to "Visit Other Site", "http://www.rubyonrails.org/", :confirm => "Are you sure?"

The two options specific to +link_to+ (:confirm and :method) are used as follows:

# => Nonsense search
link_to "Nonsense search", searches_path(:foo => "bar", :baz => "quux")

# => Ruby on Rails search
link_to "Ruby on Rails search", :controller => "searches", :query => "ruby on rails"

# => Comment wall
link_to "Comment wall", profile_path(@profile, :anchor => "wall")

+link_to+ can also produce links with anchors or query strings:

# => WRONG!
link_to "WRONG!", :controller => "articles", :id => "news", :class => "article"

Leaving the hash off gives the wrong link:

# => Articles
link_to "Articles", { :controller => "articles" }, :id => "news", :class => "article"

Be careful when using the older argument style, as an extra literal hash is needed:

# => Articles
link_to "Articles", articles_path, :id => "news", :class => "article"

Classes and ids for CSS are easy to produce:


David -- Check it out!
# =>
<% end %>
<%= @profile.name %> -- Check it out!
<%= link_to(@profile) do %>

You can use a block as well if your link target is hard to fit into the name parameter. ERb example:

# =>
Profiles
link_to "Profiles", :controller => "profiles"

is better than

# => Profiles
link_to "Profiles", profiles_path

Similarly,

# => Profile
link_to "Profile", :controller => "profiles", :action => "show", :id => @profile

in place of the older more verbose, non-resource-oriented

# => Profile
link_to "Profile", @profile

or the even pithier

# => Profile
link_to "Profile", profile_path(@profile)

your application on resources and use
and newer RESTful routes. Current Rails style favors RESTful routes whenever possible, so base
Because it relies on +url_for+, +link_to+ supports both older-style controller/action/id arguments
==== Examples

they're complete
completion of the Ajax request and performing JavaScript operations once
the link. The drivers each provide mechanisms for listening for the
driver to make an Ajax request to the URL in question instead of following
* :remote => true - This will allow the unobtrusive JavaScript
the request object's methods for post?, delete? or put?.
POST behavior, you should check for it in your controller's action by using
disabled clicking the link will have no effect. If you are relying on the
to using GET. If :href => '#' is used and the user has JavaScript
Note that if the user has JavaScript disabled, the request will fall back
while spidering your site). Supported verbs are :post, :delete and :put.
in dangerous actions like deleting a record (which search bots can follow
the HTTP verb specified. Useful for having links perform a POST operation
create an HTML form and immediately submit the form for processing using
* :method => symbol of HTTP verb - This modifier will dynamically
processed normally, otherwise no action is taken.
driver to prompt with the question specified. If the user accepts, the link is
* :confirm => 'question?' - This will allow the unobtrusive JavaScript
==== Options

end
# name
link_to(url, html_options = {}) do

end
# name
link_to(options = {}, html_options = {}) do

# is passed to url_for
# url_options, except :confirm or :method,
link_to(body, url_options = {}, html_options = {})

# posts_path
# url is a String; you can use URL helpers like
link_to(body, url, html_options = {})

==== Signatures

a name, the link itself will become the name.
link will be used in place of a referrer if none exists. If +nil+ is passed as
href for the link, or use :back to link to the referrer - a JavaScript back
of an options hash to get a link tag that uses the value of the string as the
+url_for+. It's also possible to pass a string instead
of +options+. See the valid options in the documentation for
Creates a link tag of the given +name+ using a URL created by the set
def link_to(*args, &block)
  if block_given?
    options      = args.first || {}
    html_options = args.second
    link_to(capture(&block), options, html_options)
  else
    name         = args[0]
    options      = args[1] || {}
    html_options = args[2]
    html_options = convert_options_to_data_attributes(options, html_options)
    url = url_for(options)
    if html_options
      html_options = html_options.stringify_keys
      href = html_options['href']
      tag_options = tag_options(html_options)
    else
      tag_options = nil
    end
    href_attr = "href=\"#{html_escape(url)}\"" unless href
    "<a #{href_attr}#{tag_options}>#{html_escape(name || url)}</a>".html_safe
  end
end

def link_to_if(condition, name, options = {}, html_options = {}, &block)

# => my_username
# If they are logged in...
# => Login
# If the user isn't logged in...
%>
end
link_to(@current_user.login, { :controller => "accounts", :action => "show", :id => @current_user })
link_to_if(@current_user.nil?, "Login", { :controller => "sessions", :action => "new" }) do
<%=

# => Login
# If the user isn't logged in...
<%= link_to_if(@current_user.nil?, "Login", { :controller => "sessions", :action => "new" }) %>
==== Examples

in +link_to_unless+).
accepts the name or the full argument list for +link_to_unless+ (see the examples
returned. To specialize the default behavior, you can pass a block that
+options+ if +condition+ is true, in which case only the name is
Creates a link tag of the given +name+ using a URL created by the set of
def link_to_if(condition, name, options = {}, html_options = {}, &block)
  link_to_unless !condition, name, options, html_options, &block
end

def link_to_unless(condition, name, options = {}, html_options = {}, &block)

# => Reply
# If not...
# => Reply
# If the user is logged in...
%>
end
link_to(name, { :controller => "accounts", :action => "signup" })
link_to_unless(@current_user.nil?, "Reply", { :action => "reply" }) do |name|
<%=

# => Reply
# If the user is logged in...
<%= link_to_unless(@current_user.nil?, "Reply", { :action => "reply" }) %>
==== Examples

accepts the name or the full argument list for +link_to_unless+.
than just the plaintext link text), you can pass a block that
returned. To specialize the default behavior (i.e., show a login link rather
+options+ unless +condition+ is true, in which case only the name is
Creates a link tag of the given +name+ using a URL created by the set of
def link_to_unless(condition, name, options = {}, html_options = {}, &block)
  if condition
    if block_given?
      block.arity <= 1 ? capture(name, &block) : capture(name, options, html_options, &block)
    else
      name
    end
  else
    link_to(name, options, html_options)
  end
end

def link_to_unless_current(name, options = {}, html_options = {}, &block)

%>
end
link_to("Go back", { :controller => "posts", :action => "index" })
link_to_unless_current("Comment", { :controller => "comments", :action => "new" }) do
<%=

"Go Back" link instead of a link to the comments page, we could do something like this...
action is the action given. So, if we had a comments page and wanted to render a
The implicit block given to +link_to_unless_current+ is evaluated if the current


  • About Us

  • Home


  • About Us

  • Home


  • <%= link_to_unless_current("About Us", { :action => "about" }) %>

  • <%= link_to_unless_current("Home", { :action => "index" }) %>

  • def link_to_unless_current(name, options = {}, html_options = {}, &block)
      link_to_unless current_page?(options), name, options, html_options, &block
    end

    def mail_to(email_address, name = nil, html_options = {})

    # => My email
    :subject => "This is an example email"
    mail_to "me@domain.com", "My email", :cc => "ccaddress@domain.com",

    # =>
    mail_to "me@domain.com", nil, :replace_at => "_at_", :replace_dot => "_dot_", :class => "email"

    # => My email
    mail_to "me@domain.com", "My email", :encode => "hex"

    # =>
    mail_to "me@domain.com", "My email", :encode => "javascript"

    # => me@domain.com
    mail_to "me@domain.com"
    ==== Examples

    * :bcc - Blind Carbon Copy additional recipients on the email.
    * :cc - Carbon Copy addition recipients on the email.
    * :body - Preset the body of the email.
    * :subject - Preset the subject line of the email.
    string given as the value.
    obfuscate the +email_address+ by substituting the . in the email with the
    +email_address+ is used for the link label. You can use this option to
    * :replace_dot - When the link +name+ isn't provided, the
    given as the value.
    obfuscate the +email_address+ by substituting the @ sign with the string
    +email_address+ is used for the link label. You can use this option to
    * :replace_at - When the link +name+ isn't provided, the
    encode the +email_address+ before outputting the mailto link.
    the page if the user has JavaScript disabled. Passing "hex" will hex
    eval it into the DOM of the page. This method will not show the link on
    Passing "javascript" will dynamically create and encode the mailto link then
    * :encode - This key will accept the strings "javascript" or "hex".
    ==== Options

    the email itself by passing special keys to +html_options+.
    +mail_to+ has several methods for hindering email harvesters and customizing

    HTML attributes for the link can be passed in +html_options+.
    also used as the name of the link unless +name+ is specified. Additional
    Creates a mailto link tag to the specified +email_address+, which is
    def mail_to(email_address, name = nil, html_options = {})
      email_address = html_escape(email_address)
      html_options = html_options.stringify_keys
      encode = html_options.delete("encode").to_s
      cc, bcc, subject, body = html_options.delete("cc"), html_options.delete("bcc"), html_options.delete("subject"), html_options.delete("body")
      extras = []
      extras << "cc=#{Rack::Utils.escape(cc).gsub("+", "%20")}" unless cc.nil?
      extras << "bcc=#{Rack::Utils.escape(bcc).gsub("+", "%20")}" unless bcc.nil?
      extras << "body=#{Rack::Utils.escape(body).gsub("+", "%20")}" unless body.nil?
      extras << "subject=#{Rack::Utils.escape(subject).gsub("+", "%20")}" unless subject.nil?
      extras = extras.empty? ? '' : '?' + html_escape(extras.join('&'))
      email_address_obfuscated = email_address.dup
      email_address_obfuscated.gsub!(/@/, html_options.delete("replace_at")) if html_options.has_key?("replace_at")
      email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.has_key?("replace_dot")
      string = ''
      if encode == "javascript"
        "document.write('#{content_tag("a", name || email_address_obfuscated.html_safe, html_options.merge("href" => "mailto:#{email_address}#{extras}".html_safe))}');".each_byte do |c|
          string << sprintf("%%%x", c)
        end
        "<script type=\"#{Mime::JS}\">eval(decodeURIComponent('#{string}'))</script>".html_safe
      elsif encode == "hex"
        email_address_encoded = ''
        email_address_obfuscated.each_byte do |c|
          email_address_encoded << sprintf("&#%d;", c)
        end
        protocol = 'mailto:'
        protocol.each_byte { |c| string << sprintf("&#%d;", c) }
        email_address.each_byte do |c|
          char = c.chr
          string << (char =~ /\w/ ? sprintf("%%%x", c) : char)
        end
        content_tag "a", name || email_address_encoded.html_safe, html_options.merge("href" => "#{string}#{extras}".html_safe)
      else
        content_tag "a", name || email_address_obfuscated.html_safe, html_options.merge("href" => "mailto:#{email_address}#{extras}".html_safe)
      end
    end

    def options_for_javascript(options)

    def options_for_javascript(options)
      if options.empty?
        '{}'
      else
        "{#{options.keys.map { |k| "#{k}:#{options[k]}" }.sort.join(', ')}}"
      end
    end

    def url_for(options = {})

    # => javascript:history.back()
    # if request.env["HTTP_REFERER"] is not set or is blank
    <%= url_for(:back) %>

    # => http://www.example.com
    # if request.env["HTTP_REFERER"] is set to "http://www.example.com"
    <%= url_for(:back) %>

    # => http://www.example.com
    <%= url_for("http://www.example.com") %>

    # => /workshops/5
    # calls @workshop.to_s
    <%= url_for(@workshop) %>

    # => /workshops
    # relies on Workshop answering a persisted? call (and in this case returning false)
    <%= url_for(Workshop.new) %>

    # => /testing/jump/#tax&ship
    <%= url_for(:action => 'jump', :anchor => 'tax&ship') %>

    # => /messages/play/#player
    <%= url_for(:action => 'play', :anchor => 'player') %>

    # => https://www.railsapplication.com/members/login/
    <%= url_for(:action => 'login', :controller => 'members', :only_path => false, :protocol => 'https') %>

    # => /books/find
    <%= url_for(:action => 'find', :controller => 'books') %>

    # => /blog/
    <%= url_for(:action => 'index') %>
    ==== Examples

    +admin_workshop_path+ you'll have to call that explicitly (it's impossible for +url_for+ to guess that route).
    a Workshop object will attempt to use the +workshop_path+ route. If you have a nested route, such as
    you'll trigger the named route for that record. The lookup will happen on the name of the class. So passing
    If you instead of a hash pass a record (like an Active Record or Active Resource) as the options parameter,

    ==== Relying on named routes

    * :password - Inline HTTP authentication (only plucked out if :user is also present).
    * :user - Inline HTTP authentication (only plucked out if :password is also present).
    * :protocol - Overrides the default (current) protocol if provided.
    * :host - Overrides the default (current) host if provided.
    is currently not recommended since it breaks caching.
    * :trailing_slash - If true, adds a trailing slash, as in "/archive/2005/". Note that this
    * :only_path - If true, returns the relative URL (omitting the protocol, host name, and port) (true by default unless :host is specified).
    * :anchor - Specifies the anchor name to be appended to the path.
    ==== Options

    instead of the fully qualified URL like "http://example.com/controller/action".
    :only_path is true so you'll get the relative "/controller/action"
    documentation for ActionController::Base#url_for). Note that by default
    same options as +url_for+ in Action Controller (see the
    Returns the URL for the set of +options+ provided. This takes the
    def url_for(options = {})
      options ||= {}
      url = case options
      when String
        options
      when Hash
        options = options.symbolize_keys.reverse_merge!(:only_path => options[:host].nil?)
        super
      when :back
        controller.request.env["HTTP_REFERER"] || 'javascript:history.back()'
      else
        polymorphic_path(options)
      end
      url
    end

    def url_options


    end
    controller.send(:default_url_options, *args)
    def default_url_options(*args) #:nodoc:
    Need to map default url options to controller one.
    def url_options
      return super unless controller.respond_to?(:url_options)
      controller.url_options
    end