Динамический CSS в конвейере ресурсов Rails, компилируется на лету
Я строю сайт в Rails 3.2. Прошло 3 года с тех пор, как я коснулся Rails или Ruby, так что я ржавый на обоих, плюс последний раз, когда я использовал rails, это был Rails 2.3. Излишне говорить, пожалуйста, извините за любые "простые" вопросы ниже.
Вот технические характеристики
- Мульти Теннант CMS/ Сайт магазина
- Каждый "Магазин" (он же субдомен) может иметь свой собственный внешний вид, стиль и т. Д. С помощью настроек CSS
- Настройки могут быть выполнены в пользовательском интерфейсе приложения, что позволяет пользователю изменять основные переменные Bootstrap (т.е.
@textColor
,@bodyBackground
, так далее.)
- Настройки могут быть выполнены в пользовательском интерфейсе приложения, что позволяет пользователю изменять основные переменные Bootstrap (т.е.
- Я использую
less-rails-bootstrap
жемчужина в Twitter Bootstrap, внешний вид и т.д.
Вот проблемы
- Мне нужно иметь возможность динамически выводить переменные для CSS в файл, который смешивается с Bootstrap, поэтому переменные подбираются для создания окончательного CSS
- Когда пользователь изменяет переменную для CSS, существующий стиль в основном становится недействительным. Мне нужен полный CSS, перекомпилированный и записанный обратно на диск, в поток памяти или в другое место, где я могу получить его (помните, что это использует
less
) - Мне нужен другой CSS, чтобы выплевывать на поддомен. Любые предложения о том, как подойти к этому?
Дальнейшее усложнение вопроса...
... учитывая, что мне, по сути, придется найти какой-то способ компиляции CSS на лету, это означает, что я должен включить GEMS, чего обычно не было бы в производственной среде. Производительность будет очень важна. Есть ли способ изолировать это? После того, как CSS был признан недействительным и восстановлен, я мог взять содержимое и либо записать его на диск, либо сохранить в каком-нибудь memcached / redis / etc. экземпляр для исполнения.
Любые комментарии, даже если просто указать мне в общем направлении будут оценены.
Спасибо!
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
Использованы концепции, предоставленные Мануэлем Меером (спасибо, Мануэль!) Из Kraut Computing, который можно найти по адресу http://www.krautcomputing.com/blog/2012/03/27/how-to-compile-custom-sass-stylesheets-dynamically-during-runtime/.
- Я внес некоторые коррективы в соответствии со своими потребностями, но основные концепции, проиллюстрированные Мануэлем, стали основой для моего процесса компиляции.
В моей модели (назовем это "Сайт") у меня есть фрагмент кода, который выглядит следующим образом:
# .../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
Надеюсь, это поможет. Я знаю, что это отклонение от первоначального поста, но оно отклонилось, потому что это казалось наиболее достижимым решением проблемы.
Если я не ответил на конкретный вопрос, который у вас есть, не стесняйтесь комментировать, чтобы я мог расширить, где это возможно.
Спасибо!