3
votes

I'm trying to build a CMS for my site in Rails and I want to have separate styles for all the views that people reading my site will be able to see, namely index and show views, and the views that handle creating, updating and deleting views. I understand that I should probably separate these two areas out into separate controllers and namespace all the admin ones' routes, but I'm at a loss on how to do the views.

Is there any way to specify a layout, including stylesheets and javascript files, for a specific set of controllers? Note I'm using Rails 3.1 so as things are right now all my stylesheets and scripts get compiled into single files that are served with every view.

3

3 Answers

17
votes

I was running around looking for a very similar thing. And was lucky enough to find a great tutorial article by Iain Hecker.

Backends in Rails 3.1

Its set up using Namespacing and Template Inheritance. And the best part is he uses the inherited_resources gem by Jose Valim which really cleans up your controllers.

Anyway, it really got me on the right track.

Also, what will help is in your default application.js make sure to use:

//= require_directory .

instead of

//= require_tree

This will make sprockets only load files in the current directory. Then you can add an admin/ folder with its own application.js file doing the same thing.

Then of course in you layouts/application.html.erb you use:

<%= javascript_include_tag "application" %>

And in layouts/admin/application.html.erb:

<%= javascript_include_tag "admin/application" %>

Hope that helps...

Adam.

3
votes

For CSS, I like to add some body classes in my application.html.erb that allow me to separate a) admin from non-admin, and b) the various controllers/actions from each other. Here's what my body tag often looks like

<body class="<%= 'admin' if admin? %> <%= params[:controller].parameterize %> <%= params[:controller].parameterize %>_<%= params[:action].parameterize %>">

where admin? is an ApplicationHelper method defined as follows:

def admin?
    controller.class.name.split("::").first=="Admin"
end

For JS, you need to tackle view specific javascript. For that I'm going to point you here. The multiple manifest file technique discussed there could be useful for you, as you could construct an admin.js file that contains everything you need within your Admin namespace.

UPDATE: I thought this was a good question, so I wrote up a more thorough response here

1
votes

One way of getting what I think you want would be to use a <div id="index"> index stuff .... and then use nested layouts to style the div