ruby-on-rails - Rails Assets 管道中的动态 CSS,即时编译

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

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

这是规范

  • Multi Tennant 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/等中。性能实例。

任何评论,即使只是为我指出一个大体方向,我们也将不胜感激。

谢谢!

最佳答案

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

  • 我最终切换到了 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
    
  • 使用 Kraut Computing 的 Manuel Meure(感谢您 Manuel!)在 http://www.krautcomputing.com/blog/2012/03/27/how-to-compile-custom-sass-stylesheets-dynamically-during-runtime/ 中提供的概念.

    • 我做了一些调整以满足自己的需要,但 Manuel 阐述的核心概念是我编译过程的基础。
  • 在我的模型中(我们称之为“Site”),我有一段代码如下所示:

    # .../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
    

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

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

谢谢!

关于ruby-on-rails - Rails Assets 管道中的动态 CSS,即时编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13861203/

相关文章:

ruby-on-rails - Chrome 无法在 WSL(Ubuntu 18.04)中启动,并且 Chromedriver 下存在 "DevToolsActivePort file doesn' t

ruby-on-rails - 在 Rails 3 中将 UTC 转换为本地时间

ruby-on-rails - 在 OpenShift 中运行的 Redmine 中安装插件

ruby-on-rails - 检查关系是否存在 has_one mongoid

ruby-on-rails - Rails 辅助方法 :attribute_changed? 在 Rails 3.2.15 中如何工作?

ruby-on-rails - 从 excel 文件定期更新数据集的策略

ruby-on-rails - 在控制台外运行 Rails 命令

ruby-on-rails - 在 seeds.rb 中使用 "No such file"时出现 `gets.chomp` 错误

ruby-on-rails - block 有什么用?

sunspot-rails - 在带导轨的 window 上运行的太阳黑子