Динамически визуализировать файл sass через звездочки

Я хочу от помощника отобразить некоторые переменные в шаблоне .scss.erb, который использует функцию image-url() sass:

// template.scss.erb

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

До сих пор часть ERB была простой:
(используя этот ответ о переполнении стека)

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)

Запустив этот код, sass теперь равно:

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

Однако, когда я в следующий раз попытаюсь запустить:

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

Он возвращается

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

потому что вызов Sass::Engine не предоставляет контекст Sprockets.

Если я удалю image-url() из шаблона .scss.erb и заменю его родным url(), он будет правильно отображаться как CSS, без проблем.

Итак, как мне отобразить этот шаблон в контексте sprockets?


person elstgav    schedule 05.06.2015    source источник


Ответы (2)


После изучения подобного вопроса , и много проб и ошибок, я нашел свое решение: я должен предоставить хэш :sprockets при вызове 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

Следует отметить, что view_context было передано из файла представления, но могло быть и ActionView::Base.new

person elstgav    schedule 06.06.2015
comment
Спасибо! Что-то еще, с чем я борюсь, это то, что я хотел бы, чтобы помощник image-url() SASS генерировал абсолютные пути. Любые идеи? - person Drew; 22.03.2017
comment
Не могли бы вы дать немного больше информации о view_context? Я получаю сообщение об ошибке «Нет метода» при попытке вызвать #assets для экземпляра ActionView::Base. Я уверен, что это близко к тому, что мне нужно, но я действительно не понимаю, что здесь делает контекст sprockets. - person sammms; 29.03.2017
comment
@sammms вместо того, чтобы звонить assets на view_context, вы можете позвонить на Rails.application - person bert bruynooghe; 23.05.2017
comment
Для последних версий Rails вам нужно установить config.assets.compile = true в application.rb, иначе assets будет nil в рабочей среде. Подробнее об этом на github.com/rails/sprockets-rails/issues/237 - person bert bruynooghe; 23.05.2017

После борьбы с той же проблемой я нашел живой пример той же функциональности на странице Github, на удивление не опознанный.

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

По этой ссылке есть статья автора, объясняющая метод: http://www.diatomenterprises.com/dynamically-compile-stylesheets-with-rails-and-sass/

person ErvalhouS    schedule 07.11.2016