0

我正在使用 Rails 中的站点构建器,我想使用 Sprockets SCSS 处理器渲染站点 css。由于用户可以更改颜色和徽标,因此我不能使用 Sprockets 预编译,因此我开始使用 Rails SCSS 模板处理程序来处理动态视图。

目标是在请求 /sites/43543.css 时随时编译“app/views/sites/show.css.scss”。这是我到目前为止所拥有的。您会注意到我首先通过 ERB 处理器运行模板,然后尝试通过 Sprockets 运行它。

https://gist.github.com/3870095

Manuel Meurer 提出了另一种解决方案,将 ERB 输出写入路径,然后触发 Asset Pipeline 对其进行编译。我能够让他的解决方案在本地工作,但它不会在 heroku 上工作,因为资产路径不可写。文件只能写入 tmp 目录,并且这些文件只能保证用于单个请求。

http://www.krautcomputing.com/blog/2012/03/27/how-to-compile-custom-sass-stylesheets-dynamically-during-runtime/

4

1 回答 1

2

经过漫长的一天,感谢 John Feminella 和他在 google 上的帖子,我能够解决我的问题。对我来说具有挑战性的部分是弄清楚如何创建一个新的 Sprockets::Context。幸运的是,John 的解决方案不需要上下文。

此处更新要点

尝试#1

此代码不允许从资产管道导入 css 文件。

@import "foundation";有效,因为基础作为指南针模块加载

@import "custom_css";导致错误消息提示找不到文件

def call(template)
  erb = ActionView::Template.registered_template_handler(:erb).call(template)

  %{ 
    options = Compass.configuration.to_sass_engine_options.merge(
      :syntax => :scss,
      :custom => {:resolver => ::Sass::Rails::Resolver.new(CompassRails.context)},
    )
    Sass::Engine.new((begin;#{erb};end), options).render
  }
end

尝试#2

此代码无法使用asset-data-url 嵌入base64 url

  def call(template)
    erb = ActionView::Template.registered_template_handler(:erb).call(template)

    %{
      compiler = Compass::Compiler.new *Compass.configuration.to_compiler_arguments
      options  = compiler.options.merge({
        :syntax => :scss,
        :custom => {:resolver => ::Sass::Rails::Resolver.new(CompassRails.context)},
      })
      Sass::Engine.new((begin;#{erb};end), options).render
    } 
  end

尝试 3

事实证明,您可以在创建上下文时使用空值。下面的代码在开发中工作,但在生产中引发错误。

ActionView::Template::Error (can't modify immutable index)

似乎错误发生在 Sprockets::Index 中,它在生产中用于代替 Sprockets::Environment。切换到 Sprockets::Environment 也不能​​解决问题。

  def call(template)
    erb = ActionView::Template.registered_template_handler(:erb).call(template)

    %{
      context = CompassRails.context.new(::Rails.application.assets, '', Pathname.new(''))
      resolver = ::Sass::Rails::Resolver.new(context)

      compiler = Compass::Compiler.new *Compass.configuration.to_compiler_arguments
      options  = compiler.options.merge({
        :syntax => :scss,
        :custom => {:resolver => resolver}
      })

      Sass::Engine.new((begin;#{erb};end), options).render
    }
  end
于 2012-10-11T06:10:58.260 回答