Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically render a sass file through sprockets

I want, from a helper, to render some variables in a .scss.erb template that makes use of the image-url() sass function:

// template.scss.erb

#<%= id %> {
  background-image: image-url('<%= image_file %>');
}

So far, the ERB part has been easy:
(leveraging this stack overflow answer)

vars_binding = OpenStruct.new(
                 id:         'foo', 
                 image_file: 'foo.jpg'
               ).instance_eval { binding }

template = File.read('path/to/template.scss.erb')

rendered_sass = ERB.new(template).result(vars_binding)

Running that code, sass is now equal to:

#foo {
  background-image: image-url('foo.jpg');
}

However, when I next try to run:

css = Sass::Engine.new(
  rendered_sass,
  syntax:     :scss,
  cache:      false,
  load_paths: view_context.assets.paths,
  read_cache: false,
  style:      :compressed
).render

It returns

NoMethodError: undefined method `[]' for nil:NilClass
from …/sprockets-3.2.0/lib/sprockets/sass_processor.rb:267:in `sprockets_context'

because the call to Sass::Engine doesn’t provide a Sprockets context.

If I remove image-url() from the .scss.erb template, and replace it with the native url(), it will then render correctly as CSS, no problem.

So how do I render this template within a sprockets context?

like image 659
elstgav Avatar asked Jun 05 '15 22:06

elstgav


2 Answers

After digging through a similar question, and a lot of trial and error, I found my solution: I have to supply a :sprockets hash when calling Sass::Engine.new.

css = Sass::Engine.new(
  rendered_sass,
  syntax:     :scss,
  cache:      false,
  load_paths: view_context.assets.paths,
  read_cache: false,
  style:      :compressed,

  # The key ingredient…
  sprockets:  {
    context:     view_context,
    environment: view_context.assets
  }
).render

It should be noted that view_context was passed from a view file, but it could have also been ActionView::Base.new

like image 62
elstgav Avatar answered Sep 23 '22 11:09

elstgav


After struggling with the same issue I have found a live example of the same functionality on a Github page, surprisingly not gemified.

https://github.com/BLauris/custom-css-for-user

There is an article of the author explaining the method on this link: http://www.diatomenterprises.com/dynamically-compile-stylesheets-with-rails-and-sass/

like image 40
ErvalhouS Avatar answered Sep 21 '22 11:09

ErvalhouS