Extend Sprockets to bundle mustache templates
I'm trying to include some Mustache templates into the main JS bundle. The idea is to take /app/templates/*.mustache
files, generate a JSON object, and set a window-level variable, like this:
window.Templates = {
post: "<h2>{{ title }}</h2> <p>{{ body }}</p>",
comment: "..."
}
This way the templates will be preloaded with application.js
and remain available from every Rails view.
I've read this: https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md, and now I'm trying to create a transformer for new MIME type. Like so:
module Sample
class Application < Rails::Application
// ...
config.assets.configure do |env|
env.register_mime_type 'text/mustache', extensions: ['.mustache']
env.register_transformer 'text/mustache', 'application/javascript', -> (input) {
{ data: '// THIS IS SAMPLE JS CODE GENERATED BY A TRANSFORMER' }
}
end
end
end
Adding this directive to app/assets/javascripts/application.js
file suppose to inject sample output from this transformer for each file from templates
directory:
//= require_tree ../../templates
// ^ This should point to /app/templates
But I'm getting empty result after Sprockets compiles JS. Any advice?
I just want to understand how to set up Sprockets transformer. Actual JS generation is not a problem, I've added details just for the context.
I know that there are couple of gems that can do this for Mustache and Handlebars templates (like https://github.com/leshill/handlebars_assets), but I don't want to introduce another dependency here. The extension seem to be pretty simple.
I solved it, LOL.
Transformer lambda was correct. Just needed to add a regexp to Rails.application.config.assets.precompile
to enable *.mustache
processing. Also had some troubles with overly smart Sprockets caching.
I've also replaced the labda with this class:
module Service
class MustacheTransformer
def self.call(input)
Rails.logger.debug "---> Transforming Mustache: #{input[:filename]}"
key = input[:name]
body = Oj.dump(input[:data])
obj = 'window.MustacheTemplates'
{ data: "#{obj} = #{obj} || {}; #{obj}['#{key}'] = #{body}" }
end
end
end
Seem to be working pretty neat.
This is awesome. I haven't extended sprockets myself before and that looks like it turned out rather nicely. I'm impressed! :D
Chris, you can create an episode about this. I'll share more detailed code example if you like :)