модуль ActionView::Helpers::UrlHelper
Предоставляет набор методов для создания ссылок и получения URL-адресов, зависящих от системы маршрутизации (см. ActionDispatch::Routing). Это позволяет использовать одинаковый формат ссылок в представлениях и контроллерах.
Константы
- BUTTON_TAG_METHOD_VERBS
-
Этот вспомогательный метод может быть включён в любой класс, содержащий URL-помощники маршрутов (routes.url_helpers). Некоторые методы, предоставленные здесь, будут работать только в контексте запроса (например, link_to_unless_current), который должен быть предоставлен как метод request в контексте.
Методы общего доступа
# File actionview/lib/action_view/helpers/url_helper.rb, line 293
def button_to(name = nil, options = nil, html_options = nil, &block)
html_options, options = options, name if block_given?
options ||= {}
html_options ||= {}
html_options = html_options.stringify_keys
url = options.is_a?(String) ? options : url_for(options)
remote = html_options.delete("remote")
params = html_options.delete("params")
method = html_options.delete("method").to_s
method_tag = BUTTON_TAG_METHOD_VERBS.include?(method) ? method_tag(method) : "".freeze.html_safe
form_method = method == "get" ? "get" : "post"
form_options = html_options.delete("form") || {}
form_options[:class] ||= html_options.delete("form_class") || "button_to"
form_options[:method] = form_method
form_options[:action] = url
form_options[:'data-remote'] = true if remote
request_token_tag = if form_method == "post"
request_method = method.empty? ? "post" : method
token_tag(nil, form_options: { action: url, method: request_method })
else
"".freeze
end
html_options = convert_options_to_data_attributes(options, html_options)
html_options["type"] = "submit"
button = if block_given?
content_tag("button", html_options, &block)
else
html_options["value"] = name || url
tag("input", html_options)
end
inner_tags = method_tag.safe_concat(button).safe_concat(request_token_tag)
if params
to_form_params(params).each do |param|
inner_tags.safe_concat tag(:input, type: "hidden", name: param[:name], value: param[:value])
end
end
content_tag("form", inner_tags, form_options)
end Генерирует форму, содержащую единственную кнопку, которая отправляет запрос на URL, созданный набором options. Это самый безопасный метод, чтобы убедиться, что ссылки, вызывающие изменения данных, не активируются ботами или ускорителями поиска. Если HTML-кнопка не работает с вашим макетом, вы также можете рассмотреть использование метода link_to с модификатором :method, как описано в документации link_to.
По умолчанию сгенерированный элемент формы имеет имя класса button_to, чтобы разрешить стилизацию самой формы и её дочерних элементов. Это можно изменить, используя модификатор :form_class в html_options. Вы можете контролировать поведение отправки формы и элемента ввода, используя html_options. Этот метод принимает модификатор :method, описанный в документации link_to. Если модификатор :method не указан, по умолчанию будет выполнено действие POST. Вы также можете отключить кнопку, передав disabled: true в html_options. Если вы используете RESTful маршруты, вы можете передать :method для изменения HTTP-глагола, используемого для отправки формы.
Параметры
Хэш options принимает те же параметры, что и url_for.
Есть несколько специальных html_options:
-
:method- Символ HTTP-глагола. Поддерживаемые глаголы::post,:get,:delete,:patch, и:put. По умолчанию это будет:post. -
:disabled- Если установлено в значение true, сгенерирует отключённую кнопку. -
:data- Этот параметр можно использовать для добавления пользовательских атрибутов данных. -
:remote- Если установлено в значение true, позволит драйверам Unobtrusive JavaScript управлять поведением отправки. По умолчанию это поведение является ajax отправкой. -
:form- Этот хэш будет атрибутами формы. -
:form_class- Это управляет классом формы, в которой будет размещена кнопка отправки. -
:params- Хэш параметров, которые будут отображаться как скрытые поля в форме.
Атрибуты данных
-
:confirm- Это будет использовать драйвер Unobtrusive JavaScript, чтобы запросить ответ на указанный вопрос. Если пользователь подтвердит, ссылка будет обработана нормально, в противном случае никаких действий не будет. -
:disable_with- Значение этого параметра будет использоваться в качестве значения для отключённой версии кнопки отправки при отправке формы. Эта функция предоставляется драйвером Unobtrusive JavaScript.
Примеры
<%= button_to "New", action: "new" %>
# => "<form method="post" action="/controller/new" class="button_to">
# <input value="New" type="submit" />
# </form>"
<%= button_to "New", new_articles_path %>
# => "<form method="post" action="/articles/new" class="button_to">
# <input value="New" type="submit" />
# </form>"
<%= button_to [:make_happy, @user] do %>
Make happy <strong><%= @user.name %></strong>
<% end %>
# => "<form method="post" action="/users/1/make_happy" class="button_to">
# <button type="submit">
# Make happy <strong><%= @user.name %></strong>
# </button>
# </form>"
<%= button_to "New", { action: "new" }, form_class: "new-thing" %>
# => "<form method="post" action="/controller/new" class="new-thing">
# <input value="New" type="submit" />
# </form>"
<%= button_to "Create", { action: "create" }, remote: true, form: { "data-type" => "json" } %>
# => "<form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
# <input value="Create" type="submit" />
# <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
# </form>"
<%= button_to "Delete Image", { action: "delete", id: @image.id },
method: :delete, data: { confirm: "Are you sure?" } %>
# => "<form method="post" action="/images/delete/1" class="button_to">
# <input type="hidden" name="_method" value="delete" />
# <input data-confirm='Are you sure?' value="Delete Image" type="submit" />
# <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
# </form>"
<%= button_to('Destroy', 'http://www.example.com',
method: "delete", remote: true, data: { confirm: 'Are you sure?', disable_with: 'loading...' }) %>
# => "<form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
# <input name='_method' value='delete' type='hidden' />
# <input value='Destroy' type='submit' data-disable-with='loading...' data-confirm='Are you sure?' />
# <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
# </form>"
# # File actionview/lib/action_view/helpers/url_helper.rb, line 536
def current_page?(options, check_parameters: false)
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
return false unless request.get? || request.head?
check_parameters ||= options.is_a?(Hash) && options.delete(:check_parameters)
url_string = URI.parser.unescape(url_for(options)).force_encoding(Encoding::BINARY)
# 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
# the behaviour can be disabled with check_parameters: true
request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path
request_uri = URI.parser.unescape(request_uri).force_encoding(Encoding::BINARY)
if url_string.start_with?("/") && url_string != "/"
url_string.chomp!("/")
request_uri.chomp!("/")
end
if %r{^\w+://}.match?(url_string)
url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}"
else
url_string == request_uri
end
end True, если текущий URI запроса был сгенерирован заданным options.
Примеры
Допустим, мы находимся в действии http://www.example.com/shop/checkout?order=desc&page=1.
current_page?(action: 'process')
# => false
current_page?(action: 'checkout')
# => true
current_page?(controller: 'library', action: 'checkout')
# => false
current_page?(controller: 'shop', action: 'checkout')
# => true
current_page?(controller: 'shop', action: 'checkout', order: 'asc')
# => false
current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '1')
# => true
current_page?(controller: 'shop', action: 'checkout', order: 'desc', page: '2')
# => false
current_page?('http://www.example.com/shop/checkout')
# => true
current_page?('http://www.example.com/shop/checkout', check_parameters: true)
# => false
current_page?('/shop/checkout')
# => true
current_page?('http://www.example.com/shop/checkout?order=desc&page=1')
# => true
Допустим, мы находимся в действии http://www.example.com/products с методом POST в случае неверного продукта.
current_page?(controller: 'product', action: 'index') # => false
Мы также можем передать символьные аргументы вместо строк.
# File actionview/lib/action_view/helpers/url_helper.rb, line 189
def link_to(name = nil, options = nil, html_options = nil, &block)
html_options, options, name = options, name, block if block_given?
options ||= {}
html_options = convert_options_to_data_attributes(options, html_options)
url = url_for(options)
html_options["href".freeze] ||= url
content_tag("a".freeze, name || url, html_options, &block)
end Создаёт элемент якоря заданного name с использованием URL, созданного набором options. См. допустимые параметры в документации по url_for. Также можно передать строку вместо хэша параметров, что генерирует элемент якоря, использующий значение строки в качестве значения href для ссылки. Использование :back символа вместо хэша параметров создаст ссылку на страницу-источник (JavaScript обратная ссылка будет использоваться вместо источника, если таковой отсутствует). Если nil передаётся в качестве имени, значение самой ссылки станет именем.
Подписи
link_to(body, url, html_options = {})
# url is a String; you can use URL helpers like
# posts_path
link_to(body, url_options = {}, html_options = {})
# url_options, except :method, is passed to url_for
link_to(options = {}, html_options = {}) do
# name
end
link_to(url, html_options = {}) do
# name
end
Параметры
-
:data- Этот параметр можно использовать для добавления пользовательских атрибутов данных. -
method: symbol of HTTP verb- Этот модификатор динамически создаст HTML-форму и немедленно отправит форму для обработки с использованием указанного HTTP-глагола. Полезно для создания ссылок, которые выполняют операцию POST в опасных действиях, таких как удаление записи (на которые боты поиска могут натыкаться при сканировании вашего сайта). Поддерживаемые глаголы::post,:delete,:patch, и:put. Обратите внимание, что если у пользователя отключён JavaScript, запрос будет по умолчанию выполнен с использованием GET. Еслиhref: '#'используется, а у пользователя отключён JavaScript, нажатие на ссылку не повлияет. Если вы полагаетесь на поведение POST, вы должны проверить его в действии вашего контроллера, используя методы объекта запроса дляpost?,delete?,patch?, илиput?. -
remote: true- Это позволит драйверу Unobtrusive JavaScript выполнить Ajax-запрос на указанный URL вместо перехода по ссылке. Каждый из драйверов предоставляет механизмы для отслеживания завершения Ajax-запроса и выполнения JavaScript-операций после их завершения.
Атрибуты данных
-
confirm: 'question?'- Это позволит драйверу Unobtrusive JavaScript запросить ответ на указанный вопрос (в данном случае, результирующий текст будетquestion?). Если пользователь подтвердит, ссылка будет обработана нормально, в противном случае никаких действий не будет. -
:disable_with- Значение этого параметра будет использоваться в качестве имени для отключённой версии ссылки. Эта функция предоставляется драйвером Unobtrusive JavaScript.
Примеры
Так как он зависит от url_for, link_to поддерживает аргументы старого стиля контроллер/действие/id и новые RESTful маршруты. Текущий стиль Rails отдаёт предпочтение RESTful маршрутам, когда это возможно, поэтому постройте ваше приложение на основе ресурсов и используйте
link_to "Profile", profile_path(@profile) # => <a href="/profiles/1">Profile</a>
или даже более лаконичное
link_to "Profile", @profile # => <a href="/profiles/1">Profile</a>
вместо более громоздкого и не ориентированного на ресурсы старого стиля:
link_to "Profile", controller: "profiles", action: "show", id: @profile # => <a href="/profiles/show/1">Profile</a>
Аналогично,
link_to "Profiles", profiles_path # => <a href="/profiles">Profiles</a>
лучше, чем
link_to "Profiles", controller: "profiles" # => <a href="/profiles">Profiles</a>
Вы также можете использовать блок, если цель ссылки сложно поместить в параметр имени. Пример с ERB:
<%= link_to(@profile) do %>
<strong><%= @profile.name %></strong> -- <span>Check it out!</span>
<% end %>
# => <a href="/profiles/1">
<strong>David</strong> -- <span>Check it out!</span>
</a> Классы и id для CSS легко создаются:
link_to "Articles", articles_path, id: "news", class: "article" # => <a href="/articles" class="article" id="news">Articles</a>
Будьте осторожны при использовании старого стиля аргументов, так как нужен дополнительный буквальный хэш:
link_to "Articles", { controller: "articles" }, id: "news", class: "article"
# => <a href="/articles" class="article" id="news">Articles</a>
Опускание хэша даст неправильную ссылку:
link_to "WRONG!", controller: "articles", id: "news", class: "article" # => <a href="/articles/index/news?class=article">WRONG!</a>
link_to также может создавать ссылки с якорями или строками запросов:
link_to "Comment wall", profile_path(@profile, anchor: "wall") # => <a href="/profiles/1#wall">Comment wall</a> link_to "Ruby on Rails search", controller: "searches", query: "ruby on rails" # => <a href="/searches?query=ruby+on+rails">Ruby on Rails search</a> link_to "Nonsense search", searches_path(foo: "bar", baz: "quux") # => <a href="/searches?foo=bar&baz=quux">Nonsense search</a>
Единственный параметр, специфичный для link_to (:method):
link_to("Destroy", "http://www.example.com", method: :delete)
# => <a href='http://www.example.com' rel="nofollow" data-method="delete">Destroy</a>
Вы также можете использовать пользовательские атрибуты данных с помощью параметра :data:
link_to "Visit Other Site", "http://www.rubyonrails.org/", data: { confirm: "Are you sure?" }
# => <a href="http://www.rubyonrails.org/" data-confirm="Are you sure?">Visit Other Site</a>
Также можно задать любые атрибуты ссылки, такие как target, rel, type:
link_to "External link", "http://www.rubyonrails.org/", target: "_blank", rel: "nofollow" # => <a href="http://www.rubyonrails.org/" target="_blank" rel="nofollow">External link</a>
# File actionview/lib/action_view/helpers/url_helper.rb, line 425
def link_to_if(condition, name, options = {}, html_options = {}, &block)
if condition
link_to(name, options, html_options)
else
if block_given?
block.arity <= 1 ? capture(name, &block) : capture(name, options, html_options, &block)
else
ERB::Util.html_escape(name)
end
end
end Создаёт тег ссылки заданного name с использованием URL, созданного набором options если condition true, в противном случае возвращается только имя. Для специализации стандартного поведения можно передать блок, который принимает имя или полный список аргументов для link_to_unless (см. примеры в link_to_unless).
Примеры
<%= link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) %>
# If the user isn't logged in...
# => <a href="/sessions/new/">Login</a>
<%=
link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) do
link_to(@current_user.login, { controller: "accounts", action: "show", id: @current_user })
end
%>
# If the user isn't logged in...
# => <a href="/sessions/new/">Login</a>
# If they are logged in...
# => <a href="/accounts/show/3">my_username</a> # File actionview/lib/action_view/helpers/url_helper.rb, line 401
def link_to_unless(condition, name, options = {}, html_options = {}, &block)
link_to_if !condition, name, options, html_options, &block
end Создаёт тег ссылки заданного name с использованием URL, созданного набором options если condition false, в противном случае возвращается только имя. Для специализации стандартного поведения (например, показать ссылку на вход вместо просто текста ссылки) можно передать блок, принимающий имя или полный список аргументов для link_to_unless.
Примеры
<%= link_to_unless(@current_user.nil?, "Reply", { action: "reply" }) %>
# If the user is logged in...
# => <a href="/controller/reply/">Reply</a>
<%=
link_to_unless(@current_user.nil?, "Reply", { action: "reply" }) do |name|
link_to(name, { controller: "accounts", action: "signup" })
end
%>
# If the user is logged in...
# => <a href="/controller/reply/">Reply</a>
# If not...
# => <a href="/accounts/signup">Reply</a> # File actionview/lib/action_view/helpers/url_helper.rb, line 377
def link_to_unless_current(name, options = {}, html_options = {}, &block)
link_to_unless current_page?(options), name, options, html_options, &block
end Создаёт тег ссылки указанного name с использованием URL, созданного набором options, если текущий URI запроса не совпадает с ссылками. В противном случае возвращается только имя (или выполняется заданный блок, если он существует). Вы можете передать link_to_unless_current блок, который позволит настроить стандартное поведение (например, отобразить ссылку «Начать здесь» вместо текста ссылки).
Примеры
Предположим, у вас есть навигационное меню…
<ul id="navbar">
<li><%= link_to_unless_current("Home", { action: "index" }) %></li>
<li><%= link_to_unless_current("About Us", { action: "about" }) %></li>
</ul> Если в действии «о нас», будет отображено…
<ul id="navbar"> <li><a href="/controller/index">Home</a></li> <li>About Us</li> </ul>
…но если в действии «индекс», будет отображено:
<ul id="navbar"> <li>Home</li> <li><a href="/controller/about">About Us</a></li> </ul>
Неявный блок, переданный в link_to_unless_current, вычисляется, если текущее действие равно указанному действию. Таким образом, если у нас есть страница комментариев и нужно отобразить ссылку «Вернуться назад» вместо ссылки на страницу комментариев, можно сделать следующее…
<%=
link_to_unless_current("Comment", { controller: "comments", action: "new" }) do
link_to("Go back", { controller: "posts", action: "index" })
end
%> # File actionview/lib/action_view/helpers/url_helper.rb, line 475
def mail_to(email_address, name = nil, html_options = {}, &block)
html_options, name = name, nil if block_given?
html_options = (html_options || {}).stringify_keys
extras = %w{ cc bcc body subject reply_to }.map! { |item|
option = html_options.delete(item).presence || next
"#{item.dasherize}=#{ERB::Util.url_encode(option)}"
}.compact
extras = extras.empty? ? "".freeze : "?" + extras.join("&")
encoded_email_address = ERB::Util.url_encode(email_address).gsub("%40", "@")
html_options["href"] = "mailto:#{encoded_email_address}#{extras}"
content_tag("a".freeze, name || email_address, html_options, &block)
end Создаёт тег ссылки mailto на указанный email_address, который также используется в качестве имени ссылки, если name не указан. Дополнительные HTML-атрибуты для ссылки могут быть переданы в html_options.
mail_to предоставляет несколько способов настройки электронного письма, передавая специальные ключи в html_options.
Параметры
-
:subject- Устанавливает тему письма. -
:body- Устанавливает тело письма. -
:cc- Добавляет дополнительные получателей в качестве копий. -
:bcc- Добавляет дополнительных получателей в качестве скрытых копий. -
:reply_to- Устанавливает поле «Ответ кому» письма.
Защита от спама
До версии Rails 4.0 mail_to предоставляли параметры для кодирования адреса, чтобы затруднить сбор почтовых адресов. Для использования этих параметров, установите gem actionview-encoded_mail_to.
Примеры
mail_to "me@domain.com"
# => <a href="mailto:me@domain.com">me@domain.com</a>
mail_to "me@domain.com", "My email"
# => <a href="mailto:me@domain.com">My email</a>
mail_to "me@domain.com", "My email", cc: "ccaddress@domain.com",
subject: "This is an example email"
# => <a href="mailto:me@domain.com?cc=ccaddress@domain.com&subject=This%20is%20an%20example%20email">My email</a>
Вы также можете использовать блок, если целевой адрес ссылки сложно уместить в параметр имени. Пример с ERB:
<%= mail_to "me@domain.com" do %>
<strong>Email me:</strong> <span>me@domain.com</span>
<% end %>
# => <a href="mailto:me@domain.com">
<strong>Email me:</strong> <span>me@domain.com</span>
</a>
© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.