Get SASS from database (compile passed data instead of reading from file)
I ended up using this chunk of code. Totally not elegant, but I hope it will help someone with pervertish needs.
sql.rb in sass gem dir:
require 'dbi'
require 'sass'
require config with database credentials
if File.exist?(config)
require config
SQL_OPTIONS = {
:style => :nested,
:load_paths => ['.'],
:cache => true,
:cache_location => './.sass-cache',
:syntax => :scss,
:filesystem_importer => Sass::Importers::Filesystem,
:css_location => "./public/stylesheets",
:always_update => true,
:template_location => [["scss", "css"]]
}.freeze
db = DBI.connect('dbi:ODBC:driver={SQL Server};server=' + $db_host, $db_user, $db_pass)
db.select_all('SELECT name, scope, content FROM ' + $db_name + '.dbo.scss') do | row |
File.open(Dir.pwd + '/css/' + row['name'] + '.css', 'w') do |css|
css.puts Sass::Engine.new(row['content'], SQL_OPTIONS).render
puts ' overwrite css/' + row['name'] + '.css [db]'
end
end
else
puts 'ignore database stylesheets, config_ruby doesn\'t exist'
end
In lib/sass/engine.rb I included this file at the end:
require File.expand_path(File.dirname(__FILE__) + '../../../sql')
It requires additional dbi
and dbd-odbc
gems and affects sass --update as well as --watch.
Hope this helps someone.
Import SASS file from database instead of filesystem
Since you're using Compass to compile, you can add a custom Sass importers in the Compass config file. For example, compiling using compass compile -c config.rb
, you would include something like this in your config.rb
file:
require File.join(File.dirname(__FILE__), 'importer.rb')
Sass.load_paths << Sass::Importers::Custom.new()
Then in importer.rb
in the same directory, you would include your importer definition:
module Sass
module Importers
class Custom < Base
def find(name, options)
if name == '[globals]'
options[:syntax] = :scss
options[:filename] = 'globals'
options[:importer] = self
return Sass::Engine.new("$imported-variable: blue;", options)
else
return nil
end
end
def find_relative(uri, base, options)
nil
end
def key(uri, options)
[self.class.name + ":" + uri, uri]
end
def mtime(uri, options)
nil
end
def to_s
'[custom]'
end
end
end
end
Then in your Sass file you can use the importer:
@import '[globals]';
p {
color: $imported-variable;
}
Of course, this is just a dummy implementation that only accepts a URI matching "[globals]"
. You'll need to supply your own implementation that accesses your MySQL database, as I don't have any experience with database access in Ruby. Hopefully this should get you a little closer, though, in addition to the links that @Sean has provided.
Rails - How to pass Sprockets::Context in manual sass compiling
I ended up solving this in a slightly different way - using Sass::Rails::ScssTemplate's render method. Basically, I write my altered css string out to a file and pass it into the Sass::Rails::ScssTemplate constructor. I then compile and remove the temp file when it's done. This doesn't feel great, but it's working well for me.
scheme_css_dir = "#{Rails.root}/app/assets/schemes/#{scheme}/css"
css = File.read("#{scheme_css_dir}/styles.css.scss")
variables_str = ''
scheme_variables.each do |key, value|
variables_str << "$#{key}:#{value};\n"
end
css.gsub!('@import "./variables";', variables_str)
file = Tempfile.new(['styles', '.css.scss'], scheme_css_dir)
file.write(css)
file.close
abs_path = file.path
relative_path = abs_path[Rails.root.to_s.size + 1..-1]
template = Sass::Rails::ScssTemplate.new(abs_path)
environment = Evrconnect::Application.assets
context = environment.context_class.new(
:environment => environment,
:name => relative_path,
:filename => abs_path,
:metadata => {}
)
output = template.render(context)
file.unlink
Sending dynamic variables to SASS
There seems to be a fundamental lack of understanding here so I'll provide a short answer and a longer one.
short
You can not send dynamic variables to Sass. There may be some port of it for PHP that makes it possible but using just Sass, this isn't feasible.
longer
You may want to familiarize yourself with what exactly Sass is and how it fits in to your toolkit. It sounds like you're using PHP so I imagine you'd have PHP rendering out HTML templates/doing DB magic, maybe a dash of JavaScript to do client side scripting, and you'll have CSS (plain, vanilla CSS) styling elements on your site.
Sass/SCSS (hereafter, Sass) does not replace CSS (you won't ever see <link type="text/sass">
), it simply provides a different syntax for writing styles that is later compiled into CSS.
Sass is typically compiled to CSS before you send your assets to production, it's not generated when a user requests it. There's no real connection between your Sass files and your HTML document so you would not be able to pass any variables to your Sass files.
Compile Less with Node, with dynamic variables
The 'less' package on npm will do this. You can simply pass in the custom variables in the options field. Although you have to watch out for path names in your less files, they must be absolute and not relative.
var input = fs.readFileSync(__dirname + '/../private/css/main.less', 'utf8');
var options = {
modifyVars: {
'var-name': '#000000'
}
};
less.render(input, options, function (err, result) {
// send response to end-user here
});
Related Topics
God VS. Monit for Process Monitoring
Ruby, Generate a Random Hex Color
Imagemagick 7 with Rmagick 2.16 on MACos Sierra Can't Find Magickwand.H
Ruby: Module, Require and Include
Preferred Way to Private Messages Modeling in Rails 3
How to Run Rake Tasks Within My Rails Application
How to Ban/Block Users with Devise for Rails
Ruby on Rails Gem for Google Map Integration
Ruby SASS, Unable to Resolve Dependancies
Strip Signatures and Replies from Emails
Extract Links (Urls), with Nokogiri in Ruby, from a Href HTML Tags
How Much Performance Do You Get Out a Heroku Dynos/Workers
Active Admin: Customize Only New Form