модуль 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 543
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 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 символа вместо хэша параметров сгенерирует ссылку на источник (будет использоваться 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- Это позволит драйверу неочевидного JavaScript выполнить Ajax-запрос на указанный URL вместо перехода по ссылке. Каждый драйвер предоставляет механизмы для прослушивания завершения Ajax-запроса и выполнения JavaScript-операций после их завершения.
Атрибуты данных
-
confirm: 'question?'- Это позволит драйверу неочевидного JavaScript запросить подтверждение с указанным вопросом (в этом случае результирующий текст будетquestion?. Если пользователь подтвердит, ссылка будет обработана обычно, в противном случае никаких действий не будет. -
:disable_with- Значение этого параметра будет использовано в качестве имени для отключённой версии ссылки. Эта функция предоставляется драйвером неочевидного JavaScript.
Примеры
Поскольку он зависит от url_for, link_to поддерживает как старые аргументы контроллер/действие/идентификатор, так и новые 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>
Когда имя является 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 432
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 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 482
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>
Вы также можете использовать блок, если ссылка-цель сложно уместить в параметр имени. 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–2019 David Heinemeier Hansson
Licensed under the MIT License.