class Sprockets::Context
assets. See ‘DirectiveProcessor` for an example of this.
The `Context` also collects dependencies declared by
<%= asset_url “foo.png” %>
end
def asset_url; end
include MyHelper
environment.instance_eval do
mix them into `Context` directly.
helpers by injecting them into `Environment#context_class`. Do not
are typically accessed by ERB templates. You can mix in custom
`Context` provides helper methods to all `Tilt` processors. They
def annotate_exception!(exception)
Annotates exception backtrace with the original template that
def annotate_exception!(exception) location = pathname.to_s location << ":#{@__LINE__}" if @__LINE__ exception.extend(Sprockets::EngineError) exception.sprockets_annotation = " (in #{location})" end
def asset_data_uri(path)
$('').attr('src', '<%= asset_data_uri 'avatar.jpg' %>')
#logo { background: url(<%= asset_data_uri 'logo.png' %>) }
Use `asset_data_uri` from ERB with CSS or JavaScript assets:
of the current file.
asset at the specified path, and marks that path as a dependency
Returns a Base64-encoded `data:` URI with the contents of the
def asset_data_uri(path) depend_on_asset(path) asset = environment.find_asset(path) base64 = Base64.encode64(asset.to_s).gsub(/\s+/, "") "data:#{asset.content_type};base64,#{Rack::Utils.escape(base64)}" end
def asset_requirable?(path)
Tests if target path is able to be safely required into the
def asset_requirable?(path) pathname = resolve(path) content_type = environment.content_type_of(pathname) stat = environment.stat(path) return false unless stat && stat.file? self.content_type.nil? || self.content_type == content_type end
def content_type
'text/css'
'application/javascript'
Returns content type of file
def content_type environment.content_type_of(pathname) end
def depend_on(path)
the dependency file with invalidate the cache of the
This is used for caching purposes. Any changes made to
including it.
`depend_on` allows you to state a dependency on a file without
def depend_on(path) @_dependency_paths << resolve(path).to_s nil end
def depend_on_asset(path)
file. Unlike `depend_on`, this will include recursively include
invalidate the dependency asset will invalidate the source
This is used for caching purposes. Any changes that would
without including it.
`depend_on_asset` allows you to state an asset dependency
def depend_on_asset(path) filename = resolve(path).to_s @_dependency_assets << filename nil end
def evaluate(path, options = {})
<%= evaluate "bar.js" %>
directly in another.
This allows you to capture the result of an asset and include it
Reads `path` and runs processors on the file.
def evaluate(path, options = {}) pathname = resolve(path) attributes = environment.attributes_for(pathname) processors = options[:processors] || attributes.processors if options[:data] result = options[:data] else result = Sprockets::Utils.read_unicode(pathname) end processors.each do |processor| begin template = processor.new(pathname.to_s) { result } result = template.render(self, {}) rescue Exception => e annotate_exception! e raise end end result end
def initialize(environment, logical_path, pathname)
def initialize(environment, logical_path, pathname) @environment = environment @logical_path = logical_path @pathname = pathname @__LINE__ = nil @_required_paths = [] @_dependency_paths = Set.new @_dependency_assets = Set.new([pathname.to_s]) end
def logger
def logger environment.logger end
def logical_path
# => 'application'
'app/javascripts/application.js'
Returns logical path without any file extensions.
def logical_path @logical_path[/^([^.]+)/, 0] end
def require_asset(path)
<%= require_asset "#{framework}.js" %>
require assets.
If ERB processing is enabled, you can use it to dynamically
included once.
dependency will be inserted before the file and will only be
`require_asset` declares `path` as a dependency of the file. The
def require_asset(path) pathname = resolve(path, :content_type => :self) depend_on_asset(pathname) @_required_paths << pathname.to_s nil end
def resolve(path, options = {}, &block)
# => "/path/to/app/javascripts/bar.js"
resolve("./bar.js")
# => "/path/to/app/javascripts/foo.js"
resolve("foo.js")
search.
`:content_type` restriction can be supplied to restrict the
expanded path. Relative paths will also be resolved. An optional
Given a logical path, `resolve` will find and return the fully
def resolve(path, options = {}, &block) pathname = Pathname.new(path) attributes = environment.attributes_for(pathname) if pathname.absolute? pathname elsif content_type = options[:content_type] content_type = self.content_type if content_type == :self if attributes.format_extension if content_type != attributes.content_type raise ContentTypeMismatch, "#{path} is " + "'#{attributes.content_type}', not '#{content_type}'" end end resolve(path) do |candidate| if self.content_type == environment.content_type_of(candidate) return candidate end end raise FileNotFound, "couldn't find file '#{path}'" else environment.resolve(path, :base_path => self.pathname.dirname, &block) end end
def root_path
current file is `app/javascripts/foo/bar.js`, `root_path` would
If `app/javascripts` and `app/stylesheets` are in your path, and
Returns the environment path that contains the file.
def root_path environment.paths.detect { |path| pathname.to_s[path] } end