Themeing strategies with compass

8 views
Skip to first unread message

JoshL

unread,
Aug 19, 2009, 9:27:29 AM8/19/09
to Compass
All,

I want to give my users the option of selecting from a variety of
themes for the site, similar to how BaseCamp does it. I am a heavy
compass/sass user and need something that will be scale well.

I currently define all my site colors and fonts in a single variable
file in a themes directory inside stylesheets. For example

+ root
\_app
\_stylesheets
\_themes
- blues.sass
- greens.sass
- chrome_it.sass

And then inside of my application.sass I can just select the theme I
want to use.

This works great for me as the developer, but I can't seem to come up
with a way to let the USER dynamically select a theme using this
method.

Ideally I would have a theme.sass file that would read the values from
a database and then compass would compile it, or I would be able to
create a bunch of theme files (like I have) and import the users
selection at run-time based on a cookie var or something.

Im sure others are doing this somehow and I would LOVE to hear
suggestions.

Thanks,

Josh

Brandon Mathis

unread,
Aug 19, 2009, 10:37:36 AM8/19/09
to compas...@googlegroups.com
If you're suggesting that Compass should look at a database for it's
source, that seems like a bizarre solution. Why not write the the
theme styles in separate files from your layout and typography and
then use the application logic to include the default theme, or the
theme they've selected in their user preferences. If you're not
storing user preferences in your application, you can store them in a
cookie, and then read the preference and switch the theme with
javascript.

- Brandon Mathis

JoshL

unread,
Aug 19, 2009, 11:15:06 AM8/19/09
to Compass
@Brandon

WOW you gave me a crazy idea, which works, but before I get to A
solution...

What you suggested is exactly what I am doing. I have each of the
themes in its own sass partial with a theme filename, like
_blues.sass, _greens.sass, _summer.sass. Inside each of those files I
define the colors and fonts for the themes:

!bg_color = #C0C0C0
!font_base = 'Arial'
etc

Inside of my base.sass I then do @import blues.sass and throughout ALL
my SASS files I reference the variables set. It's a very effective
and efficient themeing system.

POTENTIAL SOLUTION -

I then realized as I was typing this reply a potential solution, which
WORKED!! (no database but themeing)

I created a new file:

app > stylesheets > chrome.sass

I moved all my previous application.sass stuff to a partial called:
app > stylesheets > partials > _application.sass and inside of that I
import my _base.sass partial.

now. inside of chrome.sass I just defined all my colors like I am
doing in the themes file and at the end do an @import partials/
application.sass !!!

That's it!!! I do that for each of my theme files and Compass creates
compiled themes. Inside of my layout I can then pull from the user
model the selected theme and include that stylesheet.

Granted its a lot of compiling for compass to do but I am assuming
that compass only compiles ONCE when there are changes, correct?

Anyway, it works and has near (one line) zero redundancy. If someone
has a different approach let me know.

/j

JoshL

unread,
Aug 19, 2009, 11:18:25 AM8/19/09
to Compass
One thing to note with this solution - it really doesnt allow for the
user to create custom colors for a theme, which would be nice. I
guess they could and then run a script to generate a user_theme.sass
file, but that seems a bit nuts.

Andrew Vit

unread,
Aug 20, 2009, 3:13:36 PM8/20/09
to compas...@googlegroups.com
Hi Josh,

My solution was to use a stylesheets controller which loads the user's
settings (colors, logo image, etc.) from the database, then runs the
Sass view thru ERB before compiling. I wrote this as a rails
TemplateHandler, so any .sass file in the views/stylesheets directory
could use ERB tags.

http://gist.github.com/81534

It's theoretically "slower" to process the template twice this way
(first ERB then Sass), but with page caching it's practically
irrelevant.

Andrew Vit

Chris Eppstein

unread,
Aug 20, 2009, 3:41:47 PM8/20/09
to compas...@googlegroups.com
Depending on your network architecture, page caching is not a very good approach if you're doing per-user stylesheets.

I would suggest having a model that stores the raw sass as well as the compiled css and a controller that would fetch the css from the db and only recompiles when they update it.

I've done something like that here:

Then you can have:
class User
  belongs_to :theme, :class_name => "Stylesheet"
end

Setting http cache headers and expiring them when the stylesheet changes is left as an exercise to the reader (hint: use a query url parameter).

chris

Nathan Weizenbaum

unread,
Aug 21, 2009, 2:11:28 AM8/21/09
to compas...@googlegroups.com
The best way to make user data available to Sass is to define a Sass function that returns the values you want. But before you do so, be aware that dynamically generating CSS per-request is very expensive, so you should be sure to cache it.
Reply all
Reply to author
Forward
0 new messages