New Discussion

Notifications

You’re not receiving notifications from this thread.

Extend Sprockets to bundle mustache templates

3
Rails

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 :)

Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 88,834+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.