модуль ActionView::Helpers::AssetUrlHelper
Этот модуль предоставляет методы для генерации путей и URL-адресов к ресурсам.
image_path("rails.png")
# => "/assets/rails.png"
image_url("rails.png")
# => "http://www.example.com/assets/rails.png"
Использование хостов активов
По умолчанию Rails ссылается на эти активы на текущем хосте в папке public, но вы можете направить Rails на ссылку на активы с выделенного сервера активов, установив ActionController::Base.asset_host в конфигурации приложения, обычно в config/environments/production.rb. Например, вы определите assets.example.com как ваш хост активов таким образом, внутри блока configure ваших файлов конфигурации для конкретной среды или config/application.rb:
config.action_controller.asset_host = "assets.example.com"
Помощники учитывают это:
image_tag("rails.png")
# => <img alt="Rails" src="http://assets.example.com/assets/rails.png" />
stylesheet_link_tag("application")
# => <link href="http://assets.example.com/assets/application.css" media="screen" rel="stylesheet" />
Браузеры открывают ограниченное количество одновременных подключений к одному хосту. Точное число зависит от браузера и версии. Это ограничение может привести к тому, что некоторые загрузки активов будут ожидать завершения предыдущих активов, прежде чем они смогут начаться. Вы можете использовать %d символ подстановки в asset_host для распределения запросов по четырём хостам. Например, <tt>assets%d.example.com<tt> будет распределять запросы к активам по «assets0.example.com», …, «assets3.example.com».
image_tag("rails.png")
# => <img alt="Rails" src="http://assets0.example.com/assets/rails.png" />
stylesheet_link_tag("application")
# => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
Это может улучшить производительность загрузки активов вашего приложения. Также возможно, что сочетание дополнительной нагрузки на подключение (DNS, SSL) и общих ограничений подключения браузера может привести к тому, что это решение будет работать медленнее. Вы должны убедиться, что измеряете фактическую производительность на целевых браузерах как до, так и после этого изменения.
Чтобы реализовать соответствующие хосты, вы можете настроить четыре фактических хоста или использовать подстановку DNS для CNAME подстановки на один хост активов. Вы можете узнать больше о настройке записей CNAME DNS у вашего провайдера интернет-услуг.
Примечание: это исключительно оптимизация производительности браузера и не предназначена для балансировки нагрузки сервера. См. www.die.net/musings/page_load_time/ для контекста и www.browserscope.org/?category=network для данных о лимитах подключения.
В качестве альтернативы, вы можете более точно контролировать хост активов, установив asset_host в процедуру, как показано ниже:
ActionController::Base.asset_host = Proc.new { |source|
"http://assets#{Digest::MD5.hexdigest(source).to_i(16) % 2 + 1}.example.com"
}
image_tag("rails.png")
# => <img alt="Rails" src="http://assets1.example.com/assets/rails.png" />
stylesheet_link_tag("application")
# => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
Пример выше генерирует «assets1.example.com» и «assets2.example.com». Этот вариант полезен, например, если вам нужно меньше/больше четырёх хостов, пользовательские имена хостов и т. д.
Как вы видите, процедура принимает параметр source. Это строка с абсолютным путём к активу, например, «/assets/rails.png».
ActionController::Base.asset_host = Proc.new { |source|
if source.ends_with?('.css')
"http://stylesheets.example.com"
else
"http://assets.example.com"
end
}
image_tag("rails.png")
# => <img alt="Rails" src="http://assets.example.com/assets/rails.png" />
stylesheet_link_tag("application")
# => <link href="http://stylesheets.example.com/assets/application.css" media="screen" rel="stylesheet" />
Кроме того, вы можете запросить второй параметр request. Он особенно полезен для обслуживания активов с защищённой SSL страницей. Приведённая ниже примерная процедура отключает хостинг активов для соединений HTTPS, но всё ещё отправляет активы для обычных HTTP-запросов с хостов активов. Если у вас нет сертификатов SSL для каждого из хостов активов, этот метод позволяет избежать предупреждений в клиенте о смешанных медиа. Обратите внимание, что параметр запроса может быть не предоставлен, например, при предварительной компиляции активов с помощью задачи Rake. Убедитесь, что используете процедуру (Proc), а не лямбда-функцию, так как процедура позволяет пропускать параметры и устанавливать их в значение nil.
config.action_controller.asset_host = Proc.new { |source, request|
if request && request.ssl?
"#{request.protocol}#{request.host_with_port}"
else
"#{request.protocol}assets.example.com"
end
}
Вы также можете реализовать объект пользовательского хоста активов, который отвечает на call и принимает один или два параметра, как и процедура.
config.action_controller.asset_host = AssetHostingWithMinimumSsl.new( "http://asset%d.example.com", "https://asset1.example.com" )
Константы
- ASSET_EXTENSIONS
- ASSET_PUBLIC_DIRECTORIES
-
Сопоставляет типы активов с общедоступным каталогом.
- URI_REGEXP
Публичные методы экземпляра
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 130
def asset_path(source, options = {})
raise ArgumentError, "nil is not a valid asset source" if source.nil?
source = source.to_s
return "" unless source.present?
return source if source =~ URI_REGEXP
tail, source = source[/([\?#].+)$/], source.sub(/([\?#].+)$/, ''.freeze)
if extname = compute_asset_extname(source, options)
source = "#{source}#{extname}"
end
if source[0] != ?/
source = compute_asset_path(source, options)
end
relative_url_root = defined?(config.relative_url_root) && config.relative_url_root
if relative_url_root
source = File.join(relative_url_root, source) unless source.starts_with?("#{relative_url_root}/")
end
if host = compute_asset_host(source, options)
source = File.join(host, source)
end
"#{source}#{tail}"
end Вычисляет путь к ресурсу в общедоступном каталоге. Если установлен параметр :type, к имени файла будет добавлено расширение, и он будет помещен в соответствующий общедоступный каталог.
Все другие вспомогательные методы *_path делегируют через этот метод.
asset_path "application.js" # => /assets/application.js asset_path "application", type: :javascript # => /assets/application.js asset_path "application", type: :stylesheet # => /assets/application.css asset_path "http://www.example.com/js/xmlhr.js" # => http://www.example.com/js/xmlhr.js
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 170
def asset_url(source, options = {})
path_to_asset(source, options.merge(:protocol => :request))
end Вычисляет полный URL-адрес ресурса в общедоступном каталоге. Внутренне будет использовать asset_path, поэтому большая часть их поведения будет одинаковой. Если установлен параметр :host, он перезаписывает глобальную настройку config.action_controller.asset_host.
Все остальные параметры передаются вызову asset_path.
asset_url "application.js" # => http://example.com/assets/application.js asset_url "application.js", host: "http://cdn.example.com" # => http://cdn.example.com/assets/application.js
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 362
def audio_path(source, options = {})
path_to_asset(source, {type: :audio}.merge!(options))
end Вычисляет путь к аудиоресурсу в общедоступном каталоге audios. Полные пути от корня документа будут переданы. Используется внутри audio_tag для построения пути к аудио.
audio_path("horse") # => /audios/horse
audio_path("horse.wav") # => /audios/horse.wav
audio_path("sounds/horse.wav") # => /audios/sounds/horse.wav
audio_path("/sounds/horse.wav") # => /sounds/horse.wav
audio_path("http://www.example.com/sounds/horse.wav") # => http://www.example.com/sounds/horse.wav
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 374
def audio_url(source, options = {})
url_to_asset(source, {type: :audio}.merge!(options))
end Вычисляет полный URL-адрес аудиоресурса в общедоступном каталоге audios. Внутренне будет использовать audio_path, поэтому большая часть их поведения будет одинаковой. Так как audio_url основан на методе asset_url, вы можете установить параметр :host. Если установлен параметр :host, он перезаписывает глобальную настройку config.action_controller.asset_host.
audio_url "horse.wav", host: "http://stage.example.com" # => http://stage.example.com/horse.wav
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 182
def compute_asset_extname(source, options = {})
return if options[:extname] == false
extname = options[:extname] || ASSET_EXTENSIONS[options[:type]]
extname if extname && File.extname(source) != extname
end Вычисляет расширение для добавления к пути ресурса. Возвращает nil, если ничего добавлять не нужно.
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 211
def compute_asset_host(source = "", options = {})
request = self.request if respond_to?(:request)
host = options[:host]
host ||= config.asset_host if defined? config.asset_host
if host.respond_to?(:call)
arity = host.respond_to?(:arity) ? host.arity : host.method(:call).arity
args = [source]
args << request if request && (arity > 1 || arity < 0)
host = host.call(*args)
elsif host =~ /%d/
host = host % (Zlib.crc32(source) % 4)
end
host ||= request.base_url if request && options[:protocol] == :request
return unless host
if host =~ URI_REGEXP
host
else
protocol = options[:protocol] || config.default_asset_host_protocol || (request ? :request : :relative)
case protocol
when :relative
"//#{host}"
when :request
"#{request.protocol}#{host}"
else
"#{protocol}://#{host}"
end
end
end Выбирает хост ресурса для этого источника. Возвращает nil, если хост не установлен, хост, если не установлен подстановочный знак, хост, интерполированный с числами 0-3, если он содержит %d (число — это остаток от деления хэша источника на 4), или значение, возвращаемое при вызове call на объекте, реагирующем на вызов (proc или другом).
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 201
def compute_asset_path(source, options = {})
dir = ASSET_PUBLIC_DIRECTORIES[options[:type]] || ""
File.join(dir, source)
end Вычисляет путь к ресурсу в общедоступном каталоге. Плагины и расширения могут переопределить этот метод, чтобы указывать на пользовательские ресурсы или создавать пути или строки запросов с дайджестами.
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 387
def font_path(source, options = {})
path_to_asset(source, {type: :font}.merge!(options))
end Вычисляет путь к шрифтовому ресурсу. Полные пути от корня документа будут переданы.
font_path("font") # => /fonts/font
font_path("font.ttf") # => /fonts/font.ttf
font_path("dir/font.ttf") # => /fonts/dir/font.ttf
font_path("/dir/font.ttf") # => /dir/font.ttf
font_path("http://www.example.com/dir/font.ttf") # => http://www.example.com/dir/font.ttf
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 399
def font_url(source, options = {})
url_to_asset(source, {type: :font}.merge!(options))
end Вычисляет полный URL-адрес шрифтового ресурса. Внутренне будет использовать font_path, поэтому большая часть их поведения будет одинаковой. Так как font_url основан на методе asset_url, вы можете установить параметр :host. Если установлен параметр :host, он перезаписывает глобальную настройку config.action_controller.asset_host.
font_url "font.ttf", host: "http://stage.example.com" # => http://stage.example.com/font.ttf
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 310
def image_path(source, options = {})
path_to_asset(source, {type: :image}.merge!(options))
end Вычисляет путь к изображению. Полные пути от корня документа будут переданы. Используется внутри image_tag для построения пути к изображению:
image_path("edit") # => "/assets/edit"
image_path("edit.png") # => "/assets/edit.png"
image_path("icons/edit.png") # => "/assets/icons/edit.png"
image_path("/icons/edit.png") # => "/icons/edit.png"
image_path("http://www.example.com/img/edit.png") # => "http://www.example.com/img/edit.png"
Если у вас есть изображения в качестве ресурсов приложения, этот метод может конфликтовать с их именованными маршрутами. Псевдоним path_to_image предоставлен для предотвращения этого. Rails использует псевдоним внутренне, и авторам плагинов рекомендуется делать то же самое.
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 322
def image_url(source, options = {})
url_to_asset(source, {type: :image}.merge!(options))
end Вычисляет полный URL-адрес изображения. Внутренне будет использовать image_path, поэтому большая часть их поведения будет одинаковой. Так как image_url основан на методе asset_url, вы можете установить параметр :host. Если установлен параметр :host, он перезаписывает глобальную настройку config.action_controller.asset_host.
image_url "edit.png", host: "http://stage.example.com" # => http://stage.example.com/edit.png
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 253
def javascript_path(source, options = {})
path_to_asset(source, {type: :javascript}.merge!(options))
end Вычисляет путь к JavaScript-ресурсу в общедоступном каталоге javascripts. Если имя файла source не имеет расширения, будет добавлено .js (за исключением явных URI). Полные пути от корня документа будут переданы. Используется внутри javascript_include_tag для построения пути к скрипту.
javascript_path "xmlhr" # => /assets/xmlhr.js javascript_path "dir/xmlhr.js" # => /assets/dir/xmlhr.js javascript_path "/dir/xmlhr" # => /dir/xmlhr.js javascript_path "http://www.example.com/js/xmlhr" # => http://www.example.com/js/xmlhr javascript_path "http://www.example.com/js/xmlhr.js" # => http://www.example.com/js/xmlhr.js
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 265
def javascript_url(source, options = {})
url_to_asset(source, {type: :javascript}.merge!(options))
end Вычисляет полный URL-адрес JavaScript-ресурса в общедоступном каталоге javascripts. Внутренне будет использовать javascript_path, поэтому большая часть их поведения будет одинаковой. Так как javascript_url основан на методе asset_url, вы можете установить параметр :host. Если установлен параметр :host, он перезаписывает глобальную настройку config.action_controller.asset_host.
javascript_url "js/xmlhr.js", host: "http://stage.example.com" # => http://stage.example.com/assets/dir/xmlhr.js
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 280
def stylesheet_path(source, options = {})
path_to_asset(source, {type: :stylesheet}.merge!(options))
end Вычисляет путь к ресурсу стилей в каталоге публичных стилей. Если у файла source нет расширения, будет добавлен .css (кроме явных URI). Полные пути от корня документа будут пропущены без изменений. Используется внутри stylesheet_link_tag для построения пути к стилю.
stylesheet_path "style" # => /assets/style.css stylesheet_path "dir/style.css" # => /assets/dir/style.css stylesheet_path "/dir/style.css" # => /dir/style.css stylesheet_path "http://www.example.com/css/style" # => http://www.example.com/css/style stylesheet_path "http://www.example.com/css/style.css" # => http://www.example.com/css/style.css
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 292
def stylesheet_url(source, options = {})
url_to_asset(source, {type: :stylesheet}.merge!(options))
end Вычисляет полный URL к ресурсу стилей в каталоге публичных стилей. Будет использовать stylesheet_path внутри, поэтому большинство их функций будут аналогичны. Поскольку stylesheet_url основано на методе asset_url, вы можете установить опцию :host. Если опция :host установлена, она переопределяет глобальную настройку config.action_controller.asset_host.
stylesheet_url "css/style.css", host: "http://stage.example.com" # => http://stage.example.com/css/style.css
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 336
def video_path(source, options = {})
path_to_asset(source, {type: :video}.merge!(options))
end Вычисляет путь к видео-ресурсу в каталоге публичных видео. Полные пути от корня документа будут пропущены без изменений. Используется внутри video_tag для построения пути к видео.
video_path("hd") # => /videos/hd
video_path("hd.avi") # => /videos/hd.avi
video_path("trailers/hd.avi") # => /videos/trailers/hd.avi
video_path("/trailers/hd.avi") # => /trailers/hd.avi
video_path("http://www.example.com/vid/hd.avi") # => http://www.example.com/vid/hd.avi
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 348
def video_url(source, options = {})
url_to_asset(source, {type: :video}.merge!(options))
end Вычисляет полный URL к видео-ресурсу в каталоге публичных видео. Будет использовать video_path внутри, поэтому большинство их функций будут аналогичны. Поскольку video_url основано на методе asset_url, вы можете установить опцию :host. Если опция :host установлена, она переопределяет глобальную настройку config.action_controller.asset_host.
video_url "hd.avi", host: "http://stage.example.com" # => http://stage.example.com/hd.avi
© 2004–2018 David Heinemeier Hansson
Licensed under the MIT License.