Created
May 12, 2020 15:30
-
-
Save jamesr2323/57012b9867e1ad373e42df17e2b97e30 to your computer and use it in GitHub Desktop.
Dynamically change SASS in a multi-tenant Rails application
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This works by injecting SASS variables before the main template. As long as they are not | |
# redefined without !default later on you're good to go. | |
# Includes some local in-memory caching to not recompile SASS on every request. | |
# I've implemented it at the client (tenant) level, but it could equally be more granular, at | |
# level of some other entity in your application. | |
class AssetsController < ApplicationController | |
def styles | |
$stylesheets ||= {} | |
custom_variables = %Q{ | |
$primary-color: #{@client.get_theme_primary_color}; | |
$secondary-color: #{@client.get_theme_secondary_color}; | |
$text-color: #{@client.get_theme_text_color}; | |
} | |
hash = Digest::SHA256.hexdigest(custom_variables) | |
if Rails.env.development? # Efficiently determine if stylesheets have changed | |
hash += `find app/assets/stylesheets -type f -print0 | sort -z | xargs -0 md5sum | md5sum`.split(' ').first | |
end | |
if $stylesheets[hash].present? | |
css = $stylesheets[hash] | |
else | |
asset_source = custom_variables + File.read('app/assets/stylesheets/application.scss') | |
css = Sass::Engine.new(asset_source, { | |
syntax: :scss, | |
cache: false, | |
read_cache: false, | |
style: :compressed, | |
load_paths: [Rails.root.join('app', 'assets', 'stylesheets')] | |
}).render | |
$stylesheets[hash] = css | |
end | |
render body: css, content_type: 'text/css' | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment