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

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

  •  13-10-2022
  •  | 
  •  

문제

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!

도움이 되었습니까?

해결책

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.

다른 팁

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

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top