module ActionView::Helpers::AssetTagHelper

def self.register_javascript_expansion(expansions)




javascript_include_tag :monkey # =>

ActionView::Helpers::AssetTagHelper.register_javascript_expansion :monkey => ["head", "body", "tail"]

that the plugin installed in public/javascripts.
to be called from plugin initialization to register javascript files
is passed to javascript_include_tag. This method is typically intended
Register one or more javascript files to be included when symbol
def self.register_javascript_expansion(expansions)
  expansions.each do |key, values|
    @@javascript_expansions[key] = (@@javascript_expansions[key] || []) | Array(values)
  end
end

def self.register_javascript_include_default(*args)

def self.register_javascript_include_default(*args)
  ActiveSupport::Deprecation.warn "register_javascript_include_default is deprecated. Please " \
    "manipulate config.action_view.javascript_expansions[:defaults] directly", caller
  self.javascript_expansions[:defaults].concat args
end

def self.register_stylesheet_expansion(expansions)




stylesheet_link_tag :monkey # =>

ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion :monkey => ["head", "body", "tail"]

that the plugin installed in public/stylesheets.
to be called from plugin initialization to register stylesheet files
is passed to stylesheet_link_tag. This method is typically intended
Register one or more stylesheet files to be included when symbol
def self.register_stylesheet_expansion(expansions)
  expansions.each do |key, values|
    @@stylesheet_expansions[key] = (@@stylesheet_expansions[key] || []) | Array(values)
  end
end

def self.reset_javascript_include_default

def self.reset_javascript_include_default
  ActiveSupport::Deprecation.warn "reset_javascript_include_default is deprecated. Please manipulate " \
    "config.action_view.javascript_expansions[:defaults] directly", caller
  self.javascript_expansions[:defaults] = ['prototype', 'effects', 'dragdrop', 'controls', 'rails']
end

def asset_file_path(path)

def asset_file_path(path)
  File.join(config.assets_dir, path.split('?').first)
end

def asset_file_path!(path)

def asset_file_path!(path)
  unless is_uri?(path)
    absolute_path = asset_file_path(path)
    raise(Errno::ENOENT, "Asset file not found at '#{absolute_path}'" ) unless File.exist?(absolute_path)
    return absolute_path
  end
end

def audio_path(source)

audio_path("http://www.railsapplication.com/sounds/horse.wav") # => http://www.railsapplication.com/sounds/horse.wav
audio_path("/sounds/horse.wav") # => /sounds/horse.avi
audio_path("sounds/horse.wav") # => /audios/sounds/horse.avi
audio_path("horse.wav") # => /audios/horse.avi
audio_path("horse") # => /audios/horse
==== Examples

Used internally by +audio_tag+ to build the audio path.
Full paths from the document root will be passed through.
Computes the path to an audio asset in the public audios directory.
def audio_path(source)
  compute_public_path(source, 'audios')
end

def audio_tag(source, options = {})

def audio_tag(source, options = {})
  options.symbolize_keys!
  options[:src] = path_to_audio(source)
  tag("audio", options)
end

def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})


auto_discovery_link_tag(:rss, "http://www.example.com/feed.rss", {:title => "Example RSS"}) # =>

auto_discovery_link_tag(:rss, {:controller => "news", :action => "feed"}) # =>

auto_discovery_link_tag(:rss, {:action => "feed"}, {:title => "My RSS"}) # =>

auto_discovery_link_tag(:rss, {:action => "feed"}) # =>

auto_discovery_link_tag(:atom) # =>

auto_discovery_link_tag # =>
==== Examples

* :title - Specify the title of the link, defaults to the +type+
* :type - Override the auto-generated mime type
* :rel - Specify the relation of this link, defaults to "alternate"
==== Options

+url_options+. You can modify the LINK tag itself in +tag_options+.
:atom. Control the link options in url_for format using the
an RSS or ATOM feed. The +type+ can either be :rss (default) or
Returns a link tag that browsers and news readers can use to auto-detect
def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})
  tag(
    "link",
    "rel"   => tag_options[:rel] || "alternate",
    "type"  => tag_options[:type] || Mime::Type.lookup_by_extension(type.to_s).to_s,
    "title" => tag_options[:title] || type.to_s.upcase,
    "href"  => url_options.is_a?(Hash) ? url_for(url_options.merge(:only_path => false)) : url_options
  )
end

def collect_asset_files(*path)

def collect_asset_files(*path)
  dir = path.first
  Dir[File.join(*path.compact)].collect do |file|
    file[-(file.size - dir.size - 1)..-1].sub(/\.\w+$/, '')
  end.sort
end

def compute_asset_host(source)

invoking call if it's an object responding to call.
or the value returned from invoking the proc if it's a proc or the value from
numbers 0-3 if it contains %d (the number is the source hash mod 4),
the host if no wildcard is set, the host interpolated with the
Pick an asset host for this source. Returns +nil+ if no host is set,
def compute_asset_host(source)
  if host = config.asset_host
    if host.is_a?(Proc) || host.respond_to?(:call)
      case host.is_a?(Proc) ? host.arity : host.method(:call).arity
      when 2
        request = controller.respond_to?(:request) && controller.request
        host.call(source, request)
      else
        host.call(source)
      end
    else
      (host =~ /%d/) ? host % (source.hash % 4) : host
    end
  end
end

def compute_javascript_paths(*args)

def compute_javascript_paths(*args)
  expand_javascript_sources(*args).collect { |source| compute_public_path(source, 'javascripts', 'js', false) }
end

def compute_public_path(source, dir, ext = nil, include_host = true)

asset host, if configured, with the correct request protocol.
roots. Rewrite the asset path for cache-busting asset ids. Include
Prefix with /dir/ if lacking a leading +/+. Account for relative URL
Add the the extension +ext+ if not present. Return full URLs otherwise untouched.
def compute_public_path(source, dir, ext = nil, include_host = true)
  return source if is_uri?(source)
  source += ".#{ext}" if rewrite_extension?(source, dir, ext)
  source  = "/#{dir}/#{source}" unless source[0] == ?/
  source = rewrite_asset_path(source, config.asset_path)
  has_request = controller.respond_to?(:request)
  if has_request && include_host && source !~ %r{^#{controller.config.relative_url_root}/}
    source = "#{controller.config.relative_url_root}#{source}"
  end
  source = rewrite_host_and_protocol(source, has_request) if include_host
  source
end

def compute_stylesheet_paths(*args)

def compute_stylesheet_paths(*args)
  expand_stylesheet_sources(*args).collect { |source| compute_public_path(source, 'stylesheets', 'css', false) }
end

def determine_source(source, collection)

def determine_source(source, collection)
  case source
  when Symbol
    collection[source] || raise(ArgumentError, "No expansion found for #{source.inspect}")
  else
    source
  end
end

def ensure_javascript_sources!(sources)

def ensure_javascript_sources!(sources)
  sources.each do |source|
    asset_file_path!(compute_public_path(source, 'javascripts', 'js', false))
  end
  return sources
end

def ensure_stylesheet_sources!(sources)

def ensure_stylesheet_sources!(sources)
  sources.each do |source|
    asset_file_path!(compute_public_path(source, 'stylesheets', 'css', false))
  end
  return sources
end

def expand_javascript_sources(sources, recursive = false)

def expand_javascript_sources(sources, recursive = false)
  if sources.include?(:all)
    all_javascript_files = (collect_asset_files(config.javascripts_dir, ('**' if recursive), '*.js') - ['application']) << 'application'
    ((determine_source(:defaults, @@javascript_expansions).dup & all_javascript_files) + all_javascript_files).uniq
  else
    expanded_sources = sources.collect do |source|
      determine_source(source, @@javascript_expansions)
    end.flatten
    expanded_sources << "application" if sources.include?(:defaults) && File.exist?(File.join(config.javascripts_dir, "application.js"))
    expanded_sources
  end
end

def expand_stylesheet_sources(sources, recursive)

def expand_stylesheet_sources(sources, recursive)
  if sources.first == :all
    collect_asset_files(config.stylesheets_dir, ('**' if recursive), '*.css')
  else
    sources.collect do |source|
      determine_source(source, @@stylesheet_expansions)
    end.flatten
  end
end

def favicon_link_tag(source='/favicon.ico', options={})


<%= favicon_link_tag 'mb-icon.png', :rel => 'apple-touch-icon', :type => 'image/png' %>

The following call would generate such a tag:
will be used if you add the page to the home screen of an iPod Touch, iPhone, or iPad.
For example, Mobile Safari looks for a different LINK tag, pointing to an image that

The helper accepts an additional options hash where you can override "rel" and "type".



That's passed to +path_to_image+ as is, so it gives

<%= favicon_link_tag 'favicon.ico' %>

You may specify a different file in the first argument:



generates

<%= favicon_link_tag %>

won't see the update. Using this helper prevents that because it appends an asset ID:
root of your application and it changes later, clients that have it in their cache
Web browsers cache favicons. If you just throw a favicon.ico into the document
def favicon_link_tag(source='/favicon.ico', options={})
  tag('link', {
    :rel  => 'shortcut icon',
    :type => 'image/vnd.microsoft.icon',
    :href => path_to_image(source)
  }.merge(options.symbolize_keys))
end

def image_path(source)

plugin authors are encouraged to do so.
The alias +path_to_image+ is provided to avoid that. Rails uses the alias internally, and
If you have images as application resources this method may conflict with their named routes.

image_path("http://www.railsapplication.com/img/edit.png") # => "http://www.railsapplication.com/img/edit.png"
image_path("/icons/edit.png") # => "/icons/edit.png"
image_path("icons/edit.png") # => "/images/icons/edit.png"
image_path("edit.png") # => "/images/edit.png"
image_path("edit") # => "/images/edit"

Used internally by +image_tag+ to build the image path:
Full paths from the document root will be passed through.
Computes the path to an image asset in the public images directory.
def image_path(source)
  compute_public_path(source, 'images')
end

def image_tag(source, options = {})

Mouse
image_tag("mouse.png", :mouseover => image_path("mouse_over.png")) # =>
Mouse
image_tag("mouse.png", :mouseover => "/images/mouse_over.png") # =>
Icon
image_tag("/icons/icon.gif", :class => "menu_icon") # =>
Icon
image_tag("/icons/icon.gif", :height => '32', :width => '32') # =>
Icon
image_tag("/icons/icon.gif", :size => "16x16") # =>
Edit Entry
image_tag("icon.png", :size => "16x10", :alt => "Edit Entry") # =>
Icon
image_tag("icon.png") # =>
Icon
image_tag("icon") # =>
==== Examples

This can be used to implement an easy image toggle that fires on onmouseover.
event is fired, and sets the original image to be replaced onmouseout.
* :mouseover - Set an alternate image to be used when the onmouseover
value is not in the correct format.
width="30" and height="45". :size will be ignored if the
* :size - Supplied as "{Width}x{Height}", so "30x45" becomes
+source+ is used (capitalized and without the extension)
* :alt - If no alt text is given, the file name part of the

three additional keys for convenience and conformance:
You can add HTML attributes using the +options+. The +options+ supports
==== Options

path or a file that exists in your public images directory.
Returns an html image tag for the +source+. The +source+ can be a full
def image_tag(source, options = {})
  options.symbolize_keys!
  src = options[:src] = path_to_image(source)
  unless src =~ /^cid:/
    options[:alt] = options.fetch(:alt){ File.basename(src, '.*').capitalize }
  end
  if size = options.delete(:size)
    options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
  end
  if mouseover = options.delete(:mouseover)
    options[:onmouseover] = "this.src='#{path_to_image(mouseover)}'"
    options[:onmouseout]  = "this.src='#{src}'"
  end
  tag("img", options)
end

def is_uri?(path)

def is_uri?(path)
  path =~ %r{^[-a-z]+://|^cid:}
end

def javascript_include_tag(*sources)

javascript_include_tag :all, :cache => true, :recursive => true

The :recursive option is also available for caching:


javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when config.perform_caching is true =>




javascript_include_tag "prototype", "cart", "checkout", :cache => "shop" # when config.perform_caching is false =>


javascript_include_tag :all, :cache => true # when config.perform_caching is true =>




...


javascript_include_tag :all, :cache => true # when config.perform_caching is false =>
==== Examples

environment).
is set to true (which is the case by default for the Rails production environment, but not for the development
compressed by gzip (leading to faster transfers). Caching will only happen if config.perform_caching
You can also cache multiple javascripts into one file, which requires less HTTP connections to download and can better be

== Caching multiple javascripts into one

javascript_include_tag :all, :recursive => true

If you want Rails to search in all the subdirectories under javascripts, you should explicitly set :recursive:

all subsequently included files.
Note that the default javascript files will be included first. So Prototype and Scriptaculous are available to




...


javascript_include_tag :all # =>

You can also include all javascripts in the javascripts directory using :all as the source:

(e.g., you're going to be using a certain .js file in every action), then take a look at the register_javascript_include_default method.
Though it's not really recommended practice, if you need to extend the default JavaScript set for any reason

* = The application.js file is only referenced if it exists


...


javascript_include_tag :defaults # =>


javascript_include_tag "http://www.railsapplication.com/xmlhr.js" # =>


javascript_include_tag "http://www.railsapplication.com/xmlhr" # =>



javascript_include_tag "common.javascript", "/elsewhere/cools" # =>


javascript_include_tag "xmlhr.js" # =>


javascript_include_tag "xmlhr" # =>
==== Examples

html attributes of the script tag by passing a hash as the last argument.
javascripts directory, it will be included as well. You can modify the
:defaults, if an application.js file exists in your public
your application, pass :defaults as the source. When using
root. To include the Prototype and Scriptaculous javascript libraries in
current page or you can pass the full path relative to your document
that exist in your public/javascripts directory for inclusion into the
can pass in the filename (.js extension is optional) of javascript files
Returns an html script tag for each of the +sources+ provided. You
def javascript_include_tag(*sources)
  options = sources.extract_options!.stringify_keys
  concat  = options.delete("concat")
  cache   = concat || options.delete("cache")
  recursive = options.delete("recursive")
  if concat || (config.perform_caching && cache)
    joined_javascript_name = (cache == true ? "all" : cache) + ".js"
    joined_javascript_path = File.join(joined_javascript_name[/^#{File::SEPARATOR}/] ? config.assets_dir : config.javascripts_dir, joined_javascript_name)
    unless config.perform_caching && File.exists?(joined_javascript_path)
      write_asset_file_contents(joined_javascript_path, compute_javascript_paths(sources, recursive))
    end
    javascript_src_tag(joined_javascript_name, options)
  else
    sources = expand_javascript_sources(sources, recursive)
    ensure_javascript_sources!(sources) if cache
    sources.collect { |source| javascript_src_tag(source, options) }.join("\n").html_safe
  end
end

def javascript_path(source)

javascript_path "http://www.railsapplication.com/js/xmlhr.js" # => http://www.railsapplication.com/js/xmlhr.js
javascript_path "http://www.railsapplication.com/js/xmlhr" # => http://www.railsapplication.com/js/xmlhr
javascript_path "/dir/xmlhr" # => /dir/xmlhr.js
javascript_path "dir/xmlhr.js" # => /javascripts/dir/xmlhr.js
javascript_path "xmlhr" # => /javascripts/xmlhr.js
==== Examples

Used internally by javascript_include_tag to build the script path.
Full paths from the document root will be passed through.
If the +source+ filename has no extension, .js will be appended (except for explicit URIs)
Computes the path to a javascript asset in the public javascripts directory.
def javascript_path(source)
  compute_public_path(source, 'javascripts', 'js')
end

def javascript_src_tag(source, options)

def javascript_src_tag(source, options)
  content_tag("script", "", { "type" => Mime::JS, "src" => path_to_javascript(source) }.merge(options))
end

def join_asset_file_contents(paths)

def join_asset_file_contents(paths)
  paths.collect { |path| File.read(asset_file_path!(path)) }.join("\n\n")
end

def rails_asset_id(source)

modification time as its cache-busting asset id.
Use the RAILS_ASSET_ID environment variable or the source's
def rails_asset_id(source)
  if asset_id = ENV["RAILS_ASSET_ID"]
    asset_id
  else
    if @@cache_asset_timestamps && (asset_id = @@asset_timestamps_cache[source])
      asset_id
    else
      path = File.join(config.assets_dir, source)
      asset_id = File.exist?(path) ? File.mtime(path).to_i.to_s : ''
      if @@cache_asset_timestamps
        @@asset_timestamps_cache_guard.synchronize do
          @@asset_timestamps_cache[source] = asset_id
        end
      end
      asset_id
    end
  end
end

def rewrite_asset_path(source, path = nil)

someplace other than the query string.
Break out the asset path rewrite in case plugins wish to put the asset id
def rewrite_asset_path(source, path = nil)
  if path && path.respond_to?(:call)
    return path.call(source)
  elsif path && path.is_a?(String)
    return path % [source]
  end
  asset_id = rails_asset_id(source)
  if asset_id.blank?
    source
  else
    source + "?#{asset_id}"
  end
end

def rewrite_extension?(source, dir, ext)

def rewrite_extension?(source, dir, ext)
  source_ext = File.extname(source)[1..-1]
  ext && (source_ext.blank? || (ext != source_ext && File.exist?(File.join(config.assets_dir, dir, "#{source}.#{ext}"))))
end

def rewrite_host_and_protocol(source, has_request)

def rewrite_host_and_protocol(source, has_request)
  host = compute_asset_host(source)
  if has_request && host.present? && !is_uri?(host)
    host = "#{controller.request.protocol}#{host}"
  end
  "#{host}#{source}"
end

def stylesheet_link_tag(*sources)


stylesheet_link_tag :all, :concat => true

you have too many stylesheets for IE to load.
To force concatenation (even in development mode) set :concat to true. This is useful if

stylesheet_link_tag :all, :cache => true, :recursive => true

The :recursive option is also available for caching:


stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when config.perform_caching is true =>




stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when config.perform_caching is false =>


stylesheet_link_tag :all, :cache => true # when config.perform_caching is true =>




stylesheet_link_tag :all, :cache => true # when config.perform_caching is false =>
==== Examples

environment). Examples:
is set to true (which is the case by default for the Rails production environment, but not for the development
compressed by gzip (leading to faster transfers). Caching will only happen if config.perform_caching
You can also cache multiple stylesheets into one file, which requires less HTTP connections and can better be

== Caching multiple stylesheets into one

stylesheet_link_tag :all, :recursive => true

If you want Rails to search in all the subdirectories under stylesheets, you should explicitly set :recursive:




stylesheet_link_tag :all # =>

You can also include all styles in the stylesheets directory using :all as the source:



stylesheet_link_tag "random.styles", "/css/stylish" # =>


stylesheet_link_tag "style", :media => "print" # =>


stylesheet_link_tag "style", :media => "all" # =>


stylesheet_link_tag "http://www.railsapplication.com/style.css" # =>


stylesheet_link_tag "style.css" # =>


stylesheet_link_tag "style" # =>
==== Examples

You can modify the link attributes by passing a hash as the last argument.
you don't specify an extension, .css will be appended automatically.
Returns a stylesheet link tag for the sources specified as arguments. If
def stylesheet_link_tag(*sources)
  options = sources.extract_options!.stringify_keys
  concat  = options.delete("concat")
  cache   = concat || options.delete("cache")
  recursive = options.delete("recursive")
  if concat || (config.perform_caching && cache)
    joined_stylesheet_name = (cache == true ? "all" : cache) + ".css"
    joined_stylesheet_path = File.join(joined_stylesheet_name[/^#{File::SEPARATOR}/] ? config.assets_dir : config.stylesheets_dir, joined_stylesheet_name)
    unless config.perform_caching && File.exists?(joined_stylesheet_path)
      write_asset_file_contents(joined_stylesheet_path, compute_stylesheet_paths(sources, recursive))
    end
    stylesheet_tag(joined_stylesheet_name, options)
  else
    sources = expand_stylesheet_sources(sources, recursive)
    ensure_stylesheet_sources!(sources) if cache
    sources.collect { |source| stylesheet_tag(source, options) }.join("\n").html_safe
  end
end

def stylesheet_path(source)

stylesheet_path "http://www.railsapplication.com/css/style.css" # => http://www.railsapplication.com/css/style.css
stylesheet_path "http://www.railsapplication.com/css/style" # => http://www.railsapplication.com/css/style
stylesheet_path "/dir/style.css" # => /dir/style.css
stylesheet_path "dir/style.css" # => /stylesheets/dir/style.css
stylesheet_path "style" # => /stylesheets/style.css
==== Examples

Used internally by +stylesheet_link_tag+ to build the stylesheet path.
Full paths from the document root will be passed through.
If the +source+ filename has no extension, .css will be appended (except for explicit URIs).
Computes the path to a stylesheet asset in the public stylesheets directory.
def stylesheet_path(source)
  compute_public_path(source, 'stylesheets', 'css')
end

def stylesheet_tag(source, options)

def stylesheet_tag(source, options)
  tag("link", { "rel" => "stylesheet", "type" => Mime::CSS, "media" => "screen", "href" => html_escape(path_to_stylesheet(source)) }.merge(options), false, false)
end

def video_path(source)

video_path("http://www.railsapplication.com/vid/hd.avi") # => http://www.railsapplication.com/vid/hd.avi
video_path("/trailers/hd.avi") # => /trailers/hd.avi
video_path("trailers/hd.avi") # => /videos/trailers/hd.avi
video_path("hd.avi") # => /videos/hd.avi
video_path("hd") # => /videos/hd
==== Examples

Used internally by +video_tag+ to build the video path.
Full paths from the document root will be passed through.
Computes the path to a video asset in the public videos directory.
def video_path(source)
  compute_public_path(source, 'videos')
end

def video_tag(sources, options = {})


video_tag(["trailer.ogg", "trailer.flv"] :size => "160x120") # =>

video_tag(["trailer.ogg", "trailer.flv"]) # =>
def video_tag(sources, options = {})
  options.symbolize_keys!
  options[:poster] = path_to_image(options[:poster]) if options[:poster]
  if size = options.delete(:size)
    options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
  end
  if sources.is_a?(Array)
    content_tag("video", options) do
      sources.map { |source| tag("source", :src => source) }.join.html_safe
    end
  else
    options[:src] = path_to_video(sources)
    tag("video", options)
  end
end

def write_asset_file_contents(joined_asset_path, asset_paths)

def write_asset_file_contents(joined_asset_path, asset_paths)
  FileUtils.mkdir_p(File.dirname(joined_asset_path))
  File.atomic_write(joined_asset_path) { |cache| cache.write(join_asset_file_contents(asset_paths)) }
  # Set mtime to the latest of the combined files to allow for
  # consistent ETag without a shared filesystem.
  mt = asset_paths.map { |p| File.mtime(asset_file_path(p)) }.max
  File.utime(mt, mt, joined_asset_path)
end