Rails, won't allow stylesheets with custom extension in pipeline handled through local gem

StackOverflow https://stackoverflow.com/questions/21843977

  •  13-10-2022
  •  | 
  •  

Question

How can I pre-process CSS files with a custom extension through a gem?

I have searched for hours to figure this out, but haven't come any closer to a solution. I have looked at the gems for LESS, SASS, CoffeeScript, Ember to get a better idea but their way of handling it doesn't work for me neither.

The gem is build similar to the coffee-rails gem. Rails seems to ignore any settings I do through the gem to handle the custom extension stylesheets, and just turns the stylesheet.css.custom tag link to stylesheet.css.custom.css which gives a 404 error.

I have tried a lot, but I hope this code sums up well what I have been doing:

# lib/custom-rails.rb
config.app_generators.stylesheet_engine = :custom

# lib/custom-rails.rb
config.before_initialize do |app|
   Sprockets::Engines #force autoloading
   Sprockets.register_engine '.custom', CustomTemplate
 end

# lib/custom/custom_template.rb
ActiveSupport.on_load(:action_view) do
  ActionView::Template.register_template_handler :custom, Custom::Rails::CustomTemplate
end

I'm using Rail 4.0.1.

Any ideas how I can get the gem to handle the stylesheets? Thanks!

Was it helpful?

Solution

I finally got it working.

The key seems to be an initializer after sprockets.environment:

  initializer 'custom-rails.sprockets_engine', after: 'sprockets.environment', group: :all do |app|
    app.assets.register_engine '.custom', CustomerTemplate
  end

Here's the final code for the ones who find themselves in similar situation. I also added Tilt template to make it work well.

# lib/custom/custom_template.rb
require 'tilt'

module Custom
  module Rails
    class CustomTemplate < ::Tilt::Template
      self.default_mime_type = 'text/css'

      def prepare
      end

      def evaluate(scope, locals, &block)
        # Code for processing
      end

      def allows_script?
        false
      end
    end
  end
end

# lib/custom/engine.rb
module Custom
  module Rails
    class Engine < ::Rails::Engine
      initializer 'custom-rails.sprockets_engine', after: 'sprockets.environment', group: :all do |app|
        app.assets.register_engine '.custom', CustomerTemplate
      end
  end
end

# lib/custom/template_handler.rb
module Custom
  module Rails
    class TemplateHandler
      def self.erb_handler
        @@erb_handler ||= ActionView::Template.registered_template_handler(:erb)
      end

      def self.call(template)
        compiled_source = erb_handler.call(template)
        # Code for processing
      end
    end
  end
end

ActiveSupport.on_load(:action_view) do
  ActionView::Template.register_template_handler :custom, Custom::Rails::TemplateHandler
end

The first step of the debugging was that the .custom extension was not handled correctly. I could see that they were not handled correctly because the CSS was served in the stylesheets uri instead of the assets uri.

OTHER TIPS

As you've not had any answers, I'll give you an idea:


Override

I would imagine Rails is basically overriding your new gem & causing the custom files to be "compiled" to css. I would look to exclude any .custom files from your asset pipeline (allowing you to compile them separately):

#app/assets/application.css
/*
  *= require_self
*/

This will only include application.css.scss, meaning you can then use your gem to compile the other assets

Probably won't work, but that's my idea

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top