【问题标题】:Dynamic CSS in Rails asset pipeline, compile on flyRails 资产管道中的动态 CSS,即时编译
【发布时间】:2012-12-13 13:48:04
【问题描述】:

我正在使用 Rails 3.2 构建一个站点。我接触 Rails 或 Ruby 已经 3 年了,所以我对两者都生疏了,而且我最后一次使用 Rails 是 Rails 2.3。不用说,请原谅下面的任何“简单”问题。

这里是规格

  • 多租户 CMS/商店站点
  • 每个“商店”(也称为子域)都可以通过 CSS 自定义拥有自己的外观、感觉等
    • 可以在应用内的 UI 中执行自定义,允许用户更改 Bootstrap 的基本变量(即@textColor@bodyBackground 等)
  • 我将 less-rails-bootstrap gem 用于 Twitter Bootstrap 外观/感觉等。

以下是挑战

  1. 我需要能够将 CSS 的变量动态输出到一个文件中,该文件会混合到 Bootstrap 中,以便提取这些变量来创建最终的 CSS
  2. 当用户更改 CSS 的变量时,现有样式基本上失效。我需要重新编译完整的 CSS 并将其写回磁盘、内存流或其他我可以使用的位置(请记住这是使用 less
  3. 我需要不同的 CSS 来为每个子域输出。关于如何解决这个问题的任何建议?

让事情进一步复杂化......

...鉴于我基本上必须找到某种方法来即时编译 CSS,这意味着我必须包含 GEMS,而我通常不会在生产环境中。性能将非常重要。有没有办法隔离这个?一旦 CSS 失效并重新生成,我可以获取内容并将其写入磁盘或存储在某些 memcached/redis/etc 中。性能实例。

任何 cmets,即使只是为了给我指明一个大致的方向,我都会感激不尽。

谢谢!

【问题讨论】:

  • 您可以在动态添加的脚本中添加!important 之类的规则,以处理那些发生变化的事情。然后你就不必重新编译了
  • 这里的部分目标是能够利用 CSS 中变量的优势。这些变量在 Bootstrap 源文件中得到重用。这方面的一个例子是变量@purple。这允许用户指定我们想要使用的“紫色”的颜色(色调/饱和度等)。然后在多个地方的 Bootstrap 中使用它。不幸的是,常规 CSS 在这里不起作用。
  • Ryan,我正在寻找与您相同的答案,因为我想利用 Bootstrap 变量。当然,它在开发中有效,因为事情是动态编译的。我正在做类似的事情,因为我将客户的较少文件保存在 lib/assets/stylesheets/customers 中。然后在我的 application.html.erb 文件中,我检查是否使用子域访问了该站点,然后提供适当的文件(我在子域之后命名 .less 文件)。你有想过这个吗?如果没有,我会在你的问题上添加我自己的观点,所以我不会欺骗它。

标签: ruby-on-rails ruby ruby-on-rails-3.2 less asset-pipeline


【解决方案1】:

这是我最终找到的解决方案:

  • 我最终切换到bootstrap-sass 而不是https://github.com/thomas-mcdonald/bootstrap-sass
  • 对我的application.rb 文件进行了以下更改,以确保无论环境如何都始终包含:asset 组:

    if defined?(Bundler)
        # If you precompile assets before deploying to production, use this line
        # Bundler.require(*Rails.groups(:assets => %w(development test)))
        # If you want your assets lazily compiled in production, use this line
        Bundler.require(:default, :assets, Rails.env)
    end
    
  • 使用了由位于 http://www.krautcomputing.com/blog/2012/03/27/how-to-compile-custom-sass-stylesheets-dynamically-during-runtime/ 的 Kraut Computing 的 Manuel Meure(谢谢 Manuel!)提供的概念。

    • 我根据自己的需要进行了一些调整,但 Manuel 阐述的核心概念是我编译过程的基础。
  • 在我的模型中(我们称之为“Site”),我有一个如下所示的 sn-p 代码:

    # .../app/models/site.rb
    ...
    
    BASE_STYLE = "
      @import \"compass/css3\";
    
      <ADDITIONAL_STYLES>
    
      @import \"bootstrap\";
      @import \"bootstrap-responsive\";
    ".freeze
    
    # Provides the SASS/CSS content that would 
    # be included into your base SASS content before compilation
    def sass_content
      "
      $bodyBackground: #{self.body_background};
      $textColor: #{self.text_color};
      " + self.css # Any additional CSS/SASS you would want to add
    end
    
    def compile_css(test_only = false, force_recompile = false)
    
      # SassCompiler is a modification of the information made available at the Kraut Computing link
      compiler = SassCompiler.new("#{self.id}/site.css", {:syntax => :scss, :output_dir => Rails.root.join('app', 'assets', 'sites')})
    
      # Bail if we're already compiled and we're not forcing recompile
      return if compiler.compiled? && !force_recompile && !test_only
    
      # The block here yields the content that will be rendered
      compiler.compile(test_only) {
        # take our base styles, slap in there some vars that we make available to be customized by the user
        # and then finally add in our css/scss that the user updated... concat those and use it as
        # our raw sass to compile
        BASE_STYLE.gsub(/<ADDITIONAL_STYLES>/, self.sass_content)
      }
    end
    

我希望这会有所帮助。我知道它与原始帖子有偏差,但它有偏差,因为这似乎是解决问题的最可行的解决方案。

如果我没有回答您的具体问题,请随时发表评论,以便我尽可能扩展。

谢谢!

【讨论】:

  • 我很好奇你是否知道我将其部署到 Heroku 的方法,因为他们坚持所有部署都必须是 initialize_on_precompile = false
  • @Trip,希望我能在那个问题上给你一个好的答案。自从我进入 Rails 土地以来已经有一点时间了,不记得我是否遇到过这篇文章 - 抱歉。如果您觉得可以对此进行扩展,请随时编辑我的答案。
  • 啊,所以我确实找到了答案,并且可以将其设置为 true 进行部署,您只需要使用 Heroku 的默认构建包。从技术上讲,它应该默认运行。我的错误是在两年前,同一个应用程序有一个定制的应用程序,一些开发人员正在修补它——我没有更新它。
  • 嗨@beydogan,根据上面用于此基础的链接(来自Kraut Computing),这在Rails 4中不起作用。这是该页面上一个cmets的摘录: “此方法在 Rails 4 中不起作用,因为 Sprockets::StaticCompiler 不再是 rails 的一部分......” 我建议阅读该页面的 cmets,因为有一些关于潜在的讨论Rails 4 解决方法。
猜你喜欢
  • 2013-05-08
  • 2013-05-28
  • 1970-01-01
  • 2023-04-03
  • 2014-08-28
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 2013-07-30
相关资源
最近更新 更多