модуль ActionView::Helpers::UrlHelper
Предоставляет набор методов для создания ссылок и получения URL-адресов, зависящих от системы маршрутизации (см. ActionDispatch::Routing). Это позволяет использовать один и тот же формат для ссылок в представлениях и контроллерах.
Константы
- BUTTON_TAG_METHOD_VERBS
-
Этот помощник может быть включен в любой класс, который включает в себя помощники URL-адресов маршрутов (routes.url_helpers). Некоторые методы, представленные здесь, будут работать только в контексте запроса (
link_to_unless_current, например), который должен быть предоставлен как метод, называемый request в контексте. - STRINGIFIED_COMMON_METHODS
Открытые методы экземпляров
# File actionview/lib/action_view/helpers/url_helper.rb, line 300
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) : "".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
""
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, позволит драйверам JavaScript управлять поведением отправки. По умолчанию это поведение - отправка по Ajax. -
:form- Этот хэш будет атрибутами формы. -
:form_class- Это контролирует класс формы, в котором будет размещена кнопка отправки. -
:params- Хэш параметров, которые будут отображены как скрытые поля в форме.
Атрибуты данных
-
:confirm- Это будет использовать драйвер JavaScript для запроса подтверждения с указанным вопросом. Если пользователь согласен, ссылка обрабатывается обычно, в противном случае никаких действий не выполняется. -
:disable_with- Значение этого параметра будет использоваться как значение для отключенной версии кнопки отправки при отправке формы. Эта функция предоставляется драйвером 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_article_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 542
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::DEFAULT_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::DEFAULT_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 196
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"] ||= url
content_tag("a", name || url, html_options, &block)
end Создает элемент якоря заданного name, используя URL, созданный набором options. См. допустимые параметры в документации для url_for. Также можно передать строку вместо хэша параметров, что сгенерирует элемент якоря, использующий значение строки в качестве href для ссылки. Использование символа :back вместо хэша параметров сгенерирует ссылку на referrer (будет использован JavaScript-обратный переход вместо referrer, если он отсутствует). Если 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- Это позволит драйверам JavaScript выполнить запрос Ajax на указанный URL-адрес вместо перехода по ссылке. Каждый драйвер предоставляет механизмы для прослушивания завершения запроса Ajax и выполнения JavaScript-операций после их завершения.
Атрибуты данных
-
confirm: 'question?'- Это позволит драйверам JavaScript запросить подтверждение с указанным вопросом (в этом случае результирующий текст будетquestion?). Если пользователь согласен, ссылка обрабатывается обычно, в противном случае никаких действий не выполняется. -
:disable_with- Значение этого параметра будет использоваться как имя для отключенной версии ссылки. Эта функция предоставляется драйвером 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>
Когда name является nil, href отображается вместо него
link_to nil, "http://example.com" # => <a href="http://www.example.com">http://www.example.com</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> Классы и идентификаторы для 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 431
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_if.
Примеры
<%= 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 408
def link_to_unless(condition, name, options = {}, html_options = {}, &block)
link_to_if !condition, name, options, html_options, &block
end Создает тег ссылки заданного name с использованием URL, созданного набором options, если condition равно true, в противном случае возвращается только имя. Для специализации поведения по умолчанию (например, отображения ссылки входа, а не только текстового имени ссылки) можно передать блок, который принимает имя или весь список аргументов для 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 384
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 481
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? ? "" : "?" + extras.join("&")
encoded_email_address = ERB::Util.url_encode(email_address).gsub("%40", "@")
html_options["href"] = "mailto:#{encoded_email_address}#{extras}"
content_tag("a", 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 предоставлял варианты кодирования адреса для затруднения сбора электронных адресов. Чтобы воспользоваться этими вариантами, установите actionview-encoded_mail_to gem.
Примеры
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>
Вы также можете использовать блок, если целевой объект ссылки сложно вписать в параметр name. 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> # File actionview/lib/action_view/helpers/url_helper.rb, line 655
def phone_to(phone_number, name = nil, html_options = {}, &block)
html_options, name = name, nil if block_given?
html_options = (html_options || {}).stringify_keys
country_code = html_options.delete("country_code").presence
country_code = country_code.nil? ? "" : "+#{ERB::Util.url_encode(country_code)}"
encoded_phone_number = ERB::Util.url_encode(phone_number)
html_options["href"] = "tel:#{country_code}#{encoded_phone_number}"
content_tag("a", name || phone_number, html_options, &block)
end Создаёт тег ссылки TEL для указанного phone_number, который также используется в качестве имени ссылки, если name не указан. Дополнительные атрибуты HTML для ссылки можно передать в html_options.
При нажатии открывается приложение для звонков по умолчанию, предварительно заполненное переданным номером телефона и необязательным значением country_code.
phone_to имеет необязательный параметр country_code, который автоматически добавляет код страны и знак «+» в номер телефона, который предварительно заполняется, например, если +country_code: «01»+ ++01+ будет добавлено к номеру телефона, путём передачи специальных ключей в html_options.
Параметры
-
:country_code- Добавляет код страны к номеру
Примеры
phone_to "1234567890" # => <a href="tel:1234567890">1234567890</a> phone_to "1234567890", "Phone me" # => <a href="tel:134567890">Phone me</a> phone_to "1234567890", "Phone me", country_code: "01" # => <a href="tel:+015155555785">Phone me</a>
Вы также можете использовать блок, если целевой объект ссылки сложно вписать в параметр name. Пример ERB:
<%= phone_to "1234567890" do %>
<strong>Phone me:</strong>
<% end %>
# => <a href="tel:1234567890">
<strong>Phone me:</strong>
</a> # File actionview/lib/action_view/helpers/url_helper.rb, line 605
def sms_to(phone_number, name = nil, html_options = {}, &block)
html_options, name = name, nil if block_given?
html_options = (html_options || {}).stringify_keys
extras = %w{ body }.map! { |item|
option = html_options.delete(item).presence || next
"#{item.dasherize}=#{ERB::Util.url_encode(option)}"
}.compact
extras = extras.empty? ? "" : "?&" + extras.join("&")
encoded_phone_number = ERB::Util.url_encode(phone_number)
html_options["href"] = "sms:#{encoded_phone_number};#{extras}"
content_tag("a", name || phone_number, html_options, &block)
end Создаёт тег ссылки SMS для указанного phone_number, который также используется в качестве имени ссылки, если name не указан. Дополнительные атрибуты HTML для ссылки можно передать в html_options.
При нажатии открывается предварительно заполненное сообщение SMS с переданным номером телефона и необязательным значением body.
sms_to имеет опцию body для настройки сообщения SMS путём передачи специальных ключей в html_options.
Параметры
-
:body- Предварительно задаёт тело сообщения.
Примеры
sms_to "5155555785"
# => <a href="sms:5155555785;">5155555785</a>
sms_to "5155555785", "Text me"
# => <a href="sms:5155555785;">Text me</a>
sms_to "5155555785", "Text me",
body: "Hello Jim I have a question about your product."
# => <a href="sms:5155555785;?body=Hello%20Jim%20I%20have%20a%20question%20about%20your%20product">Text me</a>
Вы также можете использовать блок, если целевой объект ссылки сложно вписать в параметр name. Пример ERB:
<%= sms_to "5155555785" do %>
<strong>Text me:</strong>
<% end %>
# => <a href="sms:5155555785;">
<strong>Text me:</strong>
</a>
© 2004–2020 David Heinemeier Hansson
Licensed under the MIT License.