Class: Sprockets::Context

Inherits:
Object
  • Object
show all
Defined in:
lib/sprockets/context.rb

Overview

`Context` provides helper methods to all `Tilt` processors. They are typically accessed by ERB templates. You can mix in custom helpers by injecting them into `Environment#context_class`. Do not mix them into `Context` directly.

environment.context_class.class_eval do
  include MyHelper
  def asset_url; end
end

<%= asset_url "foo.png" %>

The `Context` also collects dependencies declared by assets. See `DirectiveProcessor` for an example of this.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(environment, logical_path, pathname) ⇒ Context

Returns a new instance of Context


29
30
31
32
33
34
35
36
37
38
39
# File 'lib/sprockets/context.rb', line 29

def initialize(environment, logical_path, pathname)
  @environment  = environment
  @logical_path = logical_path
  @pathname     = pathname
  @__LINE__     = nil

  @_required_paths    = []
  @_stubbed_assets    = Set.new
  @_dependency_paths  = Set.new
  @_dependency_assets = Set.new([pathname.to_s])
end

Instance Attribute Details

#__LINE__=(value) ⇒ Object (writeonly)

Sets the attribute __LINE__

Parameters:

  • value

    the value to set the attribute __LINE__ to.


27
28
29
# File 'lib/sprockets/context.rb', line 27

def __LINE__=(value)
  @__LINE__ = value
end

#_dependency_assetsObject (readonly)

Returns the value of attribute _dependency_assets


26
27
28
# File 'lib/sprockets/context.rb', line 26

def _dependency_assets
  @_dependency_assets
end

#_dependency_pathsObject (readonly)

Returns the value of attribute _dependency_paths


26
27
28
# File 'lib/sprockets/context.rb', line 26

def _dependency_paths
  @_dependency_paths
end

#_required_pathsObject (readonly)

Returns the value of attribute _required_paths


25
26
27
# File 'lib/sprockets/context.rb', line 25

def _required_paths
  @_required_paths
end

#_stubbed_assetsObject (readonly)

Returns the value of attribute _stubbed_assets


25
26
27
# File 'lib/sprockets/context.rb', line 25

def _stubbed_assets
  @_stubbed_assets
end

#environmentObject (readonly)

Returns the value of attribute environment


24
25
26
# File 'lib/sprockets/context.rb', line 24

def environment
  @environment
end

#pathnameObject (readonly)

Returns the value of attribute pathname


24
25
26
# File 'lib/sprockets/context.rb', line 24

def pathname
  @pathname
end

Instance Method Details

#asset_data_uri(path) ⇒ Object

Returns a Base64-encoded `data:` URI with the contents of the asset at the specified path, and marks that path as a dependency of the current file.

Use `asset_data_uri` from ERB with CSS or JavaScript assets:

#logo { background: url(<%= asset_data_uri 'logo.png' %>) }

$('<img>').attr('src', '<%= asset_data_uri 'avatar.jpg' %>')

217
218
219
220
221
222
# File 'lib/sprockets/context.rb', line 217

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

#asset_path(path, options = {}) ⇒ Object

Expands logical path to full url to asset.

NOTE: This helper is currently not implemented and should be customized by the application. Though, in the future, some basics implemention may be provided with different methods that are required to be overridden.


230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/sprockets/context.rb', line 230

def asset_path(path, options = {})
  message = <<-EOS
Custom asset_path helper is not implemented

Extend your environment context with a custom method.

environment.context_class.class_eval do
  def asset_path(path, options = {})
  end
end
  EOS
  raise NotImplementedError, message
end

#asset_requirable?(path) ⇒ Boolean

Tests if target path is able to be safely required into the current concatenation.

Returns:

  • (Boolean)

162
163
164
165
166
167
168
# File 'lib/sprockets/context.rb', line 162

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

#audio_path(path) ⇒ Object

Expand logical audio asset path.


255
256
257
# File 'lib/sprockets/context.rb', line 255

def audio_path(path)
  asset_path(path, :type => :audio)
end

#content_typeObject

Returns content type of file

'application/javascript'
'text/css'

64
65
66
# File 'lib/sprockets/context.rb', line 64

def content_type
  environment.content_type_of(pathname)
end

#depend_on(path) ⇒ Object

`depend_on` allows you to state a dependency on a file without including it.

This is used for caching purposes. Any changes made to the dependency file with invalidate the cache of the source file.


118
119
120
121
# File 'lib/sprockets/context.rb', line 118

def depend_on(path)
  @_dependency_paths << resolve(path).to_s
  nil
end

#depend_on_asset(path) ⇒ Object

`depend_on_asset` allows you to state an asset dependency without including it.

This is used for caching purposes. Any changes that would invalidate the dependency asset will invalidate the source file. Unlike `depend_on`, this will include recursively include the target asset's dependencies.


130
131
132
133
134
# File 'lib/sprockets/context.rb', line 130

def depend_on_asset(path)
  filename = resolve(path).to_s
  @_dependency_assets << filename
  nil
end

#evaluate(path, options = {}) ⇒ Object

Reads `path` and runs processors on the file.

This allows you to capture the result of an asset and include it directly in another.

<%= evaluate "bar.js" %>

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/sprockets/context.rb', line 177

def evaluate(path, options = {})
  pathname   = resolve(path)
  attributes = environment.attributes_for(pathname)
  processors = options[:processors] || attributes.processors

  if options[:data]
    result = options[:data]
  else
    if environment.respond_to?(:default_external_encoding)
      mime_type = environment.mime_types(pathname.extname)
      encoding  = environment.encoding_for_mime_type(mime_type)
      result    = Sprockets::Utils.read_unicode(pathname, encoding)
    else
      result = Sprockets::Utils.read_unicode(pathname)
    end
  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

#font_path(path) ⇒ Object

Expand logical font asset path.


260
261
262
# File 'lib/sprockets/context.rb', line 260

def font_path(path)
  asset_path(path, :type => :font)
end

#image_path(path) ⇒ Object

Expand logical image asset path.


245
246
247
# File 'lib/sprockets/context.rb', line 245

def image_path(path)
  asset_path(path, :type => :image)
end

#javascript_path(path) ⇒ Object

Expand logical javascript asset path.


265
266
267
# File 'lib/sprockets/context.rb', line 265

def javascript_path(path)
  asset_path(path, :type => :javascript)
end

#logical_pathObject

Returns logical path without any file extensions.

'app/javascripts/application.js'
# => 'application'

55
56
57
# File 'lib/sprockets/context.rb', line 55

def logical_path
  @logical_path.chomp(File.extname(@logical_path))
end

#require_asset(path) ⇒ Object

`require_asset` declares `path` as a dependency of the file. The dependency will be inserted before the file and will only be included once.

If ERB processing is enabled, you can use it to dynamically require assets.

<%= require_asset "#{framework}.js" %>

145
146
147
148
149
150
# File 'lib/sprockets/context.rb', line 145

def require_asset(path)
  pathname = resolve(path, :content_type => :self)
  depend_on_asset(pathname)
  @_required_paths << pathname.to_s
  nil
end

#resolve(path, options = {}, &block) ⇒ Object

Given a logical path, `resolve` will find and return the fully expanded path. Relative paths will also be resolved. An optional `:content_type` restriction can be supplied to restrict the search.

resolve("foo.js")
# => "/path/to/app/javascripts/foo.js"

resolve("./bar.js")
# => "/path/to/app/javascripts/bar.js"

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/sprockets/context.rb', line 79

def resolve(path, options = {}, &block)
  pathname   = Pathname.new(path)
  attributes = environment.attributes_for(pathname)

  if pathname.absolute?
    if environment.stat(pathname)
      pathname
    else
      raise FileNotFound, "couldn't find file '#{pathname}'"
    end

  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}.merge(options), &block)
  end
end

#root_pathObject

Returns the environment path that contains the file.

If `app/javascripts` and `app/stylesheets` are in your path, and current file is `app/javascripts/foo/bar.js`, `root_path` would return `app/javascripts`.


46
47
48
# File 'lib/sprockets/context.rb', line 46

def root_path
  environment.paths.detect { |path| pathname.to_s[path] }
end

#stub_asset(path) ⇒ Object

`stub_asset` blacklists `path` from being included in the bundle. `path` must be an asset which may or may not already be included in the bundle.


155
156
157
158
# File 'lib/sprockets/context.rb', line 155

def stub_asset(path)
  @_stubbed_assets << resolve(path, :content_type => :self).to_s
  nil
end

#stylesheet_path(path) ⇒ Object

Expand logical stylesheet asset path.


270
271
272
# File 'lib/sprockets/context.rb', line 270

def stylesheet_path(path)
  asset_path(path, :type => :stylesheet)
end

#video_path(path) ⇒ Object

Expand logical video asset path.


250
251
252
# File 'lib/sprockets/context.rb', line 250

def video_path(path)
  asset_path(path, :type => :video)
end