documentcloud/jammit — pull request #229 by dinedal (2012-04-24 15:07:44+00:00)
Title: Allow Jammit to be extended to package and compress other types of assests

I use Jammit on a production level service and am happy with it, however I came across a need to be able to package and compress other static assets that are not stylesheets, javascripts, or JSTs.

In order to do this, the attached changes are needed to be able to allow me to extend Jammit with custom asset types. It is important to me to keep using Jammit, and I would greatly appreciate this functionality being merged into the main repo, and I'm open to any changes you feel are needed to get this in.

Below is a modified version of what I am using to interact with the fork of Jammit with these included changes.

```
module Jammit

JSON_NAMESPACE = "window.DATA"

JSON_FUNCTION = "JSON.parse"

JSON_EXTENSION = "json"

class Compressor
# no actual compression applied, just formats it correctly, but could support compression
def compress_json(paths)
namespace = JSON_NAMESPACE
base_path = find_base_path(paths)
compiled = paths.map do |path|
contents = read_binary_file(path)
name = json_name(path, base_path)
"#{namespace}['#{name}'] = #{JSON_FUNCTION}('#{contents}');"
end
setup_namespace = "#{namespace} = #{namespace} || {};"
[JST_START, setup_namespace, compiled, JST_END].flatten.join("\n")
end

def json_name(path, base_path)
return File.basename(path, ".#{JSON_EXTENSION}") unless base_path
path.gsub(/\A#{Regexp.escape(base_path)}\/(.*)\.#{JSON_EXTENSION}\Z/, '\1')
end
end

class Packager
def pack_jsons(package)
compressor.compress_json(package_for(package, :json)[:paths])
end
end

module Helper
def include_jsons(*packages)
options = packages.extract_options!
html_safe packages.map {|pack|
Jammit.asset_url(pack, :json)
}.flatten.map {|pack|
javascript_include_tag pack, options
}.join("\n")
end
end
end
```

Please note that this is a initial pass and is very conservative in what it changes, however a couple of more drastic changes could make this functionality more streamlined with the rest of the project.

Ideally, I feel that JSTs should also be broken out ouf the Javascript packaging / compression, and the pipeline of packaging and compressing be made more generic to support handling user defined asset types as a first class citizen. Thus, each type, user defined or included, will flow through a similar work flow.

However, before embarking on this, I would greatly appreciate feedback on what I have so far, how to determine what asset type (JS or CSS) an asset supplied in the assets.yml would be, and if the way user defined templates are created is acceptable.