Module: ActionView::Helpers::UrlHelper

Includes:
JavaScriptHelper
Defined in:
lib/action_view/helpers/url_helper.rb

Overview

Provides a set of methods for making easy links and getting urls that depend on the controller and action. This means that you can use the same format for links in the views that you do in the controller. The different methods are even named synchronously, so link_to uses that same url as is generated by url_for, which again is the same url used for redirection in redirect_to.

Constant Summary

Constants included from JavaScriptHelper

JavaScriptHelper::JAVASCRIPT_PATH

Instance Method Summary collapse

Methods included from JavaScriptHelper

#button_to_function, #define_javascript_functions, #escape_javascript, #javascript_cdata_section, #javascript_tag, #link_to_function

Instance Method Details

#button_to(name, options = {}, html_options = nil) ⇒ Object

Generates a form containing a sole button that submits to the URL given by options. Use this method instead of link_to for actions that do not have the safe HTTP GET semantics implied by using a hypertext link.

The parameters are the same as for link_to. Any html_options that you pass will be applied to the inner input element. In particular, pass

:disabled => true/false

as part of html_options to control whether the button is disabled. The generated form element is given the class 'button-to', to which you can attach CSS styles for display purposes.

Example 1:

# inside of controller for "feeds"
button_to "Edit", :action => 'edit', :id => 3

Generates the following HTML (sans formatting):

<form method="post" action="/feeds/edit/3" class="button-to">
  <div><input value="Edit" type="submit" /></div>
</form>

Example 2:

button_to "Destroy", { :action => 'destroy', :id => 3 },
          :confirm => "Are you sure?"

Generates the following HTML (sans formatting):

<form method="post" action="/feeds/destroy/3" class="button-to">
  <div><input onclick="return confirm('Are you sure?');"
              value="Destroy" type="submit" />
  </div>
</form>

NOTE: This method generates HTML code that represents a form. Forms are “block” content, which means that you should not try to insert them into your HTML where only inline content is expected. For example, you can legally insert a form inside of a div or td element or in between p elements, but not in the middle of a run of text, nor can you place a form within another form. (Bottom line: Always validate your HTML before going public.)


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/action_view/helpers/url_helper.rb', line 110

def button_to(name, options = {}, html_options = nil)
  html_options = (html_options || {}).stringify_keys
  convert_boolean_attributes!(html_options, %w( disabled ))
  
  if confirm = html_options.delete("confirm")
    html_options["onclick"] = "return #{confirm_javascript_function(confirm)};"
  end
  
  url = options.is_a?(String) ? options : url_for(options)
  name ||= url
  
  html_options.merge!("type" => "submit", "value" => name)

  "<form method=\"post\" action=\"#{h url}\" class=\"button-to\"><div>" +
    tag("input", html_options) + "</div></form>"
end

#current_page?(options) ⇒ Boolean

Returns true if the current page uri is generated by the options passed (in url_for format).

Returns:

  • (Boolean)

246
247
248
# File 'lib/action_view/helpers/url_helper.rb', line 246

def current_page?(options)
  CGI.escapeHTML(url_for(options)) == @controller.request.request_uri
end

This tag is deprecated. Combine the link_to and AssetTagHelper::image_tag yourself instead, like:

link_to(image_tag("rss", :size => "30x45", :border => 0), "http://www.example.com")

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/action_view/helpers/url_helper.rb', line 130

def link_image_to(src, options = {}, html_options = {}, *parameters_for_method_reference)
  image_options = { "src" => src.include?("/") ? src : "/images/#{src}" }
  image_options["src"] += ".png" unless image_options["src"].include?(".")

  html_options = html_options.stringify_keys
  if html_options["alt"]
    image_options["alt"] = html_options["alt"]
    html_options.delete "alt"
  else
    image_options["alt"] = src.split("/").last.split(".").first.capitalize
  end

  if html_options["size"]
    image_options["width"], image_options["height"] = html_options["size"].split("x")
    html_options.delete "size"
  end

  if html_options["border"]
    image_options["border"] = html_options["border"]
    html_options.delete "border"
  end

  if html_options["align"]
    image_options["align"] = html_options["align"]
    html_options.delete "align"
  end

  link_to(tag("img", image_options), options, html_options, *parameters_for_method_reference)
end

Creates a link tag of the given name using an URL created by the set of options. See the valid options in the documentation for ActionController::Base#url_for. It's also possible to pass a string instead of an options hash to get a link tag that just points without consideration. If nil is passed as a name, the link itself will become the name.

The html_options has three special features. One for creating javascript confirm alerts where if you pass :confirm => 'Are you sure?', the link will be guarded with a JS popup asking that question. If the user accepts, the link is processed, otherwise not.

Another for creating a popup window, which is done by either passing :popup with true or the options of the window in Javascript form.

And a third for making the link do a POST request (instead of the regular GET) through a dynamically added form element that is instantly submitted. Note that if the user has turned off Javascript, the request will fall back on the GET. So its your responsibility to determine what the action should be once it arrives at the controller. The POST form is turned on by passing :post as true. Note, it's not possible to use POST requests and popup targets at the same time (an exception will be thrown).

Examples:

link_to "Delete this page", { :action => "destroy", :id => @page.id }, :confirm => "Are you sure?"
link_to "Help", { :action => "help" }, :popup => true
link_to "Busy loop", { :action => "busy" }, :popup => ['new_window', 'height=300,width=600']
link_to "Destroy account", { :action => "destroy" }, :confirm => "Are you sure?", :post => true

51
52
53
54
55
56
57
58
59
60
61
# File 'lib/action_view/helpers/url_helper.rb', line 51

def link_to(name, options = {}, html_options = nil, *parameters_for_method_reference)
  if html_options
    html_options = html_options.stringify_keys
    convert_options_to_javascript!(html_options)
    tag_options = tag_options(html_options)
  else
    tag_options = nil
  end
  url = options.is_a?(String) ? options : self.url_for(options, *parameters_for_method_reference)
  "<a href=\"#{url}\"#{tag_options}>#{name || url}</a>"
end

Create a link tag of the given name using an URL created by the set of options, if condition is true, in which case only the name is returned (or the given block is yielded, if one exists).


186
187
188
# File 'lib/action_view/helpers/url_helper.rb', line 186

def link_to_if(condition, name, options = {}, html_options = {}, *parameters_for_method_reference, &block)
  link_to_unless !condition, name, options, html_options, *parameters_for_method_reference, &block
end

Create a link tag of the given name using an URL created by the set of options, unless condition is true, in which case only the name is returned (or the given block is yielded, if one exists).


172
173
174
175
176
177
178
179
180
181
182
# File 'lib/action_view/helpers/url_helper.rb', line 172

def link_to_unless(condition, name, options = {}, html_options = {}, *parameters_for_method_reference, &block)
  if condition
    if block_given?
      block.arity <= 1 ? yield(name) : yield(name, options, html_options, *parameters_for_method_reference)
    else
      name
    end
  else
    link_to(name, options, html_options, *parameters_for_method_reference)
  end  
end

Creates a link tag of the given name using an URL created by the set of options, unless the current request uri is the same as the link's, in which case only the name is returned (or the given block is yielded, if one exists). This is useful for creating link bars where you don't want to link to the page currently being viewed.


166
167
168
# File 'lib/action_view/helpers/url_helper.rb', line 166

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

#mail_to(email_address, name = nil, html_options = {}) ⇒ Object

Creates a link tag for starting an email to the specified email_address, which is also used as the name of the link unless name is specified. Additional HTML options, such as class or id, can be passed in the html_options hash.

You can also make it difficult for spiders to harvest email address by obfuscating them. Examples:

mail_to "[email protected]", "My email", :encode => "javascript"  # =>
  <script type="text/javascript" language="javascript">eval(unescape('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%22%3e%4d%79%20%65%6d%61%69%6c%3c%2f%61%3e%27%29%3b'))</script>

mail_to "[email protected]", "My email", :encode => "hex"  # =>
  <a href="mailto:%6d%[email protected]%64%6f%6d%61%69%6e.%63%6f%6d">My email</a>

You can also specify the cc address, bcc address, subject, and body parts of the message header to create a complex e-mail using the corresponding cc, bcc, subject, and body html_options keys. Each of these options are URI escaped and then appended to the email_address before being output. Be aware that javascript keywords will not be escaped and may break this feature when encoding with javascript. Examples:

mail_to "[email protected]", "My email", :cc => "[email protected]", :bcc => "[email protected]", :subject => "This is an example email", :body => "This is the body of the message."   # =>
  <a href="mailto:[email protected]?cc="[email protected]"&bcc="[email protected]"&body="This%20is%20the%20body%20of%20the%20message."&subject="This%20is%20an%20example%20email">My email</a>

208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/action_view/helpers/url_helper.rb', line 208

def mail_to(email_address, name = nil, html_options = {})
  html_options = html_options.stringify_keys
  encode = html_options.delete("encode")
  cc, bcc, subject, body = html_options.delete("cc"), html_options.delete("bcc"), html_options.delete("subject"), html_options.delete("body")

  string = ''
  extras = ''
  extras << "cc=#{CGI.escape(cc).gsub("+", "%20")}&" unless cc.nil?
  extras << "bcc=#{CGI.escape(bcc).gsub("+", "%20")}&" unless bcc.nil?
  extras << "body=#{CGI.escape(body).gsub("+", "%20")}&" unless body.nil?
  extras << "subject=#{CGI.escape(subject).gsub("+", "%20")}&" unless subject.nil?
  extras = "?" << extras.gsub!(/&?$/,"") unless extras.empty?

  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")

  if encode == 'javascript'
    tmp = "document.write('#{("a", name || email_address, html_options.merge({ "href" => "mailto:"+email_address.to_s+extras }))}');"
    for i in 0...tmp.length
      string << sprintf("%%%x",tmp[i])
    end
    "<script type=\"text/javascript\">eval(unescape('#{string}'))</script>"
  elsif encode == 'hex'
    for i in 0...email_address.length
      if email_address[i,1] =~ /\w/
        string << sprintf("%%%x",email_address[i])
      else
        string << email_address[i,1]
      end
    end
     "a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:#{string}#{extras}" })
  else
     "a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:#{email_address}#{extras}" })
  end
end

#url_for(options = {}, *parameters_for_method_reference) ⇒ Object

Returns the URL for the set of options provided. This takes the same options as url_for. For a list, see the documentation for ActionController::Base#url_for. Note that it'll set :only_path => true so you'll get /controller/action instead of the example.com/controller/action part (makes it harder to parse httpd log files)

When called from a view, url_for returns an HTML escaped url. If you need an unescaped url, pass :escape => false to url_for.


20
21
22
23
24
25
26
27
28
29
# File 'lib/action_view/helpers/url_helper.rb', line 20

def url_for(options = {}, *parameters_for_method_reference)
  if options.kind_of? Hash
    options = { :only_path => true }.update(options.symbolize_keys)
    escape = options.key?(:escape) ? options.delete(:escape) : true
  else
    escape = true
  end
  url = @controller.send(:url_for, options, *parameters_for_method_reference)
  escape ? html_escape(url) : url
end