Get SASS from Database (Compile Passed Data Instead of Reading from File)

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



Leave a reply



Submit