Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sprockets v3.7.0 deprecation warning #292

Closed
kamen-hursev opened this issue Aug 1, 2016 · 6 comments
Closed

Sprockets v3.7.0 deprecation warning #292

kamen-hursev opened this issue Aug 1, 2016 · 6 comments

Comments

@kamen-hursev
Copy link

I use haml in some asset templates. After I updated Sprockets to v3.7. I got a deprecation warning:

DEPRECATION WARNING: You are using the a deprecated processor interface Tilt::HamlTemplate.
Please update your processor interface:
https://github.com/rails/sprockets/blob/master/guides/extending_sprockets.md#supporting-all-versions-of-sprockets-in-processors

It seems to me this is not limited to Haml, but all template engines supported by Tilt. Is Tilt::Template supposed to implement self.call in order to support Sprockets v4?

The code that triggers the warning is a Rails initializer:

Rails.application.config.assets.configure do |config|
  config.register_mime_type 'text/html', extensions: ['.haml', '.html.haml']
  config.register_preprocessor 'text/html', Tilt::HamlTemplate
end
@judofyr
Copy link
Collaborator

judofyr commented Aug 1, 2016

Sprockets was initially based on Tilt, but in the later versions they've decided to not make its interface compatible with Tilt. That is a completely fair decision as Tilt templates and Sprocket processors have different use cases.

There are no plans to change Tilt to be compatible with Sprockets v4. I think you can solve the problem by writing a class which implements call in redirects it to Tilt:

class TiltProcessor
  def initialize(template_class)
    @template_class = template_class
  end

  def call(input)
    # not sure if I've implemented this correctly
    result = @template_class.new(input[:filename]) { input[:data] }.render
    { data: result }
  end
end

config.register_preprocessor 'text/html', TiltProcessor.new(Tilt::HamlTemplate)

@kamen-hursev
Copy link
Author

Thanks, @judofyr , for the code snippet. It (almost) works, just had to change the call method to:

def call(input)
  result = @template_class.new(input[:filename]) { input[:data] }.render
  { data: String.new(result) }
end

Because for some reason Sprockets insists the data is instance_of?(String) and in some cases I get ActiveSupport::SafeBuffer.

I encountered another problem. In the haml templates I use some view helpers and used to include them like:

Rails.application.config.assets.configure do |config|
  ...
  include ActionView::Helpers
  include Rails.application.routes.url_helpers
end

For some reason after using
config.register_preprocessor 'text/html', TiltProcessor.new(Tilt::HamlTemplate)
they are not included in the Haml processor and get errors like:
NoMethodError: undefined method 'image_tag'. Do you have any idea how this can be solved?

@judofyr
Copy link
Collaborator

judofyr commented Aug 1, 2016

You could maybe do something like this:

class TiltProcessor
  def initialize(template_class)
    @template_class = template_class
  end

  def context
    @context ||= Object.new
  end

  def call(input)
    result = @template_class.new(input[:filename]) { input[:data] }.render(context)
    { data: result }
  end
end

And then you can extend it into the context:

processor = TiltProcessor.new(Tilt::HamlTemplate)
processor.context.extend Rails.application.routes.url_helpers
config.register_preprocessor 'text/html', processor

@kamen-hursev
Copy link
Author

@judofyr, thank you very much for helping me with this!
Just a note that extend won't work with modules like ActionView::Helpers. So the final solution that works for me is:

class TiltProcessor
  def initialize(template_class, context = nil)
    @template_class = template_class
    @context = context || Object.new
  end

  def call(input)
    result = @template_class.new(input[:filename]) { input[:data] }.render(@context)
    { data: String.new(result) }
  end
end

class HamlAssetsContext
  include SimpleForm::Helpers
  include SimpleForm::ActionViewExtensions::FormHelper
  include ActionView::Helpers
  include Rails.application.routes.url_helpers
  # Include any other view helper module that you need. eg:
  # include ApplicationHelper
end

Rails.application.config.assets.configure do |config|
  config.register_mime_type 'text/html', extensions: ['.haml', '.html.haml']
  processor = TiltProcessor.new(Tilt::HamlTemplate, HamlAssetsContext.new)
  config.register_preprocessor 'text/html', processor
end

@judofyr
Copy link
Collaborator

judofyr commented Aug 1, 2016

Very happy you found a solution :) I'm closing this issue now. Feel free to reopen or comment if you have any other issues/questions.

(One tiny suggestion: Change the initializer to def initialize(template_class, context = Object.new))

@judofyr judofyr closed this as completed Aug 1, 2016
@kamen-hursev
Copy link
Author

The above solution has some issues related with the context. For example image_tag, would not render correct URL-s with the hashed tail.

After some more research I managed to find my way around to sprockets legacy_tilt_processor.rb. Adding the final version here, just in case this issue attracts more people with the same/similar problem.

# For Rails add to a file in config/initializers
class TiltProcessor
  def initialize(klass)
    @klass = klass
  end

  def call(input)
    filename = input[:filename]
    data     = input[:data]
    context  = input[:environment].context_class.new(input)

    data = @klass.new(filename) { data }.render(context, {})
    context.metadata.merge(data: data.to_str)
  end
end

Rails.application.config.assets.configure do |env|
  env.context_class.class_eval do
    include SimpleForm::Helpers
    include SimpleForm::ActionViewExtensions::FormHelper
    include ActionView::Helpers
    include Rails.application.routes.url_helpers
    # Include any other view helper module that you need. eg:
    # include ApplicationHelper
  end

  env.register_mime_type 'text/html', extensions: ['.haml', '.html.haml']
  env.register_preprocessor 'text/html', TiltProcessor.new(Tilt::HamlTemplate)
end

Just don't understand why the Sprockets' processor class needs to inherit Delegator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants