module Roda::RodaPlugins::Assets::InstanceMethods
def asset_last_modified(file)
other files, check the modification times of all dependencies and
Return when the file was last modified. If the file depends on any
def asset_last_modified(file) if deps = self.class.assets_opts[:dependencies][file] ([file] + Array(deps)).map{|f| ::File.stat(f).mtime}.max else ::File.stat(file).mtime end end
def assets(type, attrs = nil)
tag for each asset file. When the assets are compiled, this will
When the assets are not compiled, this will result in a separate
the type, such as [:css, :frontend].
To return the tags for a specific asset group, use an array for
the :css type.
This will use a script tag for the :js type and a link tag for
Return a string containing html tags for the given asset type.
def assets(type, attrs = nil) o = self.class.assets_opts type, *dirs = type if type.is_a?(Array) stype = type.to_s attrs = if attrs ru = Rack::Utils attrs.map{|k,v| "#{k}=\"#{ru.escape_html(v.to_s)}\""}.join(SPACE) else EMPTY_STRING end if type == :js tag_start = "<script type=\"text/javascript\" #{attrs} src=\"/" tag_end = JS_END else tag_start = "<link rel=\"stylesheet\" #{attrs} href=\"/" tag_end = CSS_END end # Create a tag for each individual file if compiled = o[:compiled] if dirs && !dirs.empty? key = dirs.join(DOT) ckey = "#{stype}.#{key}" if ukey = compiled[ckey] "#{tag_start}#{o[:"compiled_#{stype}_prefix"]}.#{key}.#{ukey}.#{stype}#{tag_end}" end elsif ukey = compiled[stype] "#{tag_start}#{o[:"compiled_#{stype}_prefix"]}.#{ukey}.#{stype}#{tag_end}" end else asset_dir = o[type] if dirs && !dirs.empty? dirs.each{|f| asset_dir = asset_dir[f]} prefix = "#{dirs.join(SLASH)}/" if o[:group_subdirs] end Array(asset_dir).map{|f| "#{tag_start}#{o[:"#{stype}_prefix"]}#{prefix}#{f}#{o[:"#{stype}_suffix"]}#{tag_end}"}.join(NEWLINE) end end
def check_asset_request(file, type, mtime)
a 304 response immediately. Otherwise, add the appropriate
If the asset hasn't been modified since the last request, return
def check_asset_request(file, type, mtime) @_request.last_modified(mtime) @_response.headers.merge!(self.class.assets_opts[:"#{type}_headers"]) end
def read_asset_file(file, type)
Otherwise, render the file using the render plugin. +file+ should be
Return the content of the file if it is already of the correct type.
def read_asset_file(file, type) if file.end_with?(".#{type}") ::File.read(file) else render_asset_file(file, :template_opts=>self.class.assets_opts[:"#{type}_opts"]) end end
def render_asset(file, type)
In both cases, if the file has not been modified since the last request,
this will render the asset using the render plugin.
When assets are not compiled and the file is not already of the correct,
this returns the contents of the compiled file.
or when the file is already of the given type (no rendering necessary),
Render the asset with the given filename. When assets are compiled,
def render_asset(file, type) o = self.class.assets_opts if o[:compiled] file = "#{o[:"compiled_#{type}_path"]}#{file}" check_asset_request(file, type, ::File.stat(file).mtime) ::File.read(file) else file = "#{o[:"#{type}_path"]}#{file}" check_asset_request(file, type, asset_last_modified(file)) read_asset_file(file, type) end end
def render_asset_file(file, options)
Render the given asset file using the render plugin, with the given options.
def render_asset_file(file, options) render({:path => file}, options) end