Accessing Rails Controller instance variables in CSS
Asked Answered
S

2

8

So I've seen lots of discussion on SO about using erb in your CSS files. I can get ERB to process the CSS files by using the <%= %> syntax and adding .erb to the file, but what I really need is to access instance variables in the controller.

searches_controller.rb

def new
  @search = Search.new
  @school = School.find(params[:school])
end

What I would really like to do is:

searches.css.scss.erb

h1.logo {
  color: <%= @school.primary_color %>;
}

but ERB will throw an error because @school is nil. Is there some way to require the controller to access those instance variables?

The only other way I can think to do it is to embed it as an data-attribute in the views and then use JS to change it on the front end. This strikes me as potentially better since the CSS file won't change and need to be resent every time, but it would also be a lot less elegant.

Sokol answered 19/12, 2012 at 1:11 Comment(0)
I
9

You also need to consider that in a pre-compiled asset scenario, the CSS will be run through Sprockets during compilation, so you'd end up with a static colour (assuming @school was actually instantiated which it wouldn't be). This is undesirable as every school would then have the same colour (whatever that happened to be during compilation stage).

For custom branding like this we let our users specify their colours, and include a block of CSS in the layout:

:css
    h1.logo {
        color: <%= @school.primary_color %>;
    }

It isn't ideal, but if you have a small number of customisations seems to work fairly well.

Isodynamic answered 19/12, 2012 at 1:28 Comment(2)
Thanks. I was hoping to deal with it outside of the views, but it seems this is the way to go.Sokol
Can you please provide more detail on adding a css block to a layout...? I'd like to swap images based on screen size and need a way for my media queries to see my instance variables.Epp
S
2

I'd rather use the @school.primary_color in your view. This should work:

<h1 style="color:#{@school.primary_color}">@school.name</h1>

Just remember to use double quotation marks for interpolation.

Sugarplum answered 19/12, 2012 at 1:31 Comment(3)
I try to take care of nil as early as possible. So in this case, the view would never be fed a nil object. But if that's a concern then the whole view should really be wrapped in a conditional. It's not specific to just this usage.Sugarplum
Only issue with this is if you have to use that colour in multiple places in multiple views, you end up with some pretty unmaintainable code.Isodynamic
That's a good point. Depending on the number of schools, it may even be a good idea to define constants in the CSS files for each school instead of in the db.Sugarplum

© 2022 - 2024 — McMap. All rights reserved.