using a different style for different views in rails - ruby-on-rails

Rails 5.1
I mostly work on backend issues, but I am trying to learn more about front end stuff, and I am a little confused about how styles are handled in Rails (I read through a bunch of answers on stackolverflow, but that did not help narrow it down for me).
I have two different views
views/user/login.html.slim
views/user/new.html.slim
I would like to apply different body styles to each view. When the application was generated, Rails added:
assets/stylesheets/users.css.scss
Would I need to add a folder, called users and inside it, have different stylesheets? something like this:
assets/stylesheets/users/login.css.scss
would have in it:
body {
padding-top: 40px;
}
and
assets/stylesheets/users/new.css.scss
would have in it:
body {
padding-top: 80px;
}
Then, in
stylesheets/application.css.scss
I would add:
*= require_self
*= require_tree .

The styles and javascripts are loaded from your layout. Out of the box it looks like this:
app/views/layouts/application.html.erb
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application' %>
If you only want to include particular css files in a particular view, you would need to:
Create a layout for your particular view.
Include the appropriate styles and javascripts in the layout.
Specify the particular layout in your controller.
Here is some more information on layouts, but lets go through it for your login example.
app/controllers/sessions/create
class SessionsController < ApplicationController
layout 'login', only: [:new]
# you could also call the layout "sessions.html.erb" and it will be
# loaded automagically
If you want to use a different layout for different actions in the same controller, you can add other layout methods and specify the actions they apply to with the only action.
Then the layout
app/views/layouts/login.html.erb
...
<%= stylesheet_link_tag 'login', media: 'all' %>
...
And finally your stylesheet
app/assets/stylesheets/login.scss
#import "file_you_want";
If you require_tree . it will load all styles in the stylesheets directory which I don't think is what you are after.

Related

How to inject active_admin header into custom layout?

I'm try to custom active_admin layout for specific action.But I dont know how can i add active_admin's header into my custom layout?
app/admin/provider.rb
I render edit page with custom_active_admin layout
controller do
def edit
#provider = Provider.find(params[:id])
render 'admin/providers/edit', layout: 'custom_active_admin'
end
...
end
app/views/admin/providers/edit.html.haml
= semantic_form_for ...
= f.inputs 'Location', for: :location do |location|
= location.input :postal_code
= location.input :prefecture
app/views/layouts/custom_active_admin.html.haml
I'm try to custom layout for my special action
!!!
%html
%head
= csrf_meta_tags
= csp_meta_tag
...
= stylesheet_link_tag 'custom_active_admin', media: 'all'
= javascript_include_tag 'custom_active_admin'
%body.new.active_admin.logged_in.admin_namespace
#header
= yield :head
.wrapper.without_sidebar#active_admin_content
.main_content_wrapper
.alert-message-container
= yield
My custom action can work fine. But i need add header to top page like those pages using default active_admin layout. How i can do it? Thanks.
You can register custom stylesheets and javascript in the config initializer. I recommend just adding the CSS & JS into your active admin config:
# config/initializers/active_admin.rb
# == Register Stylesheets & Javascripts
#
# We recommend using the built in Active Admin layout and loading
# up your own stylesheets / javascripts to customize the look
# and feel.
#
# To load a stylesheet:
config.register_stylesheet 'my_stylesheet.css'
#
# You can provide an options hash for more control, which is passed along to stylesheet_link_tag():
# config.register_stylesheet 'my_print_stylesheet.css', media: :print
#
# To load a javascript file:
config.register_javascript 'my_javascript.js'
If you feel strongly that the JS should only be on that single view, you can include it in the view itself.
for example, in an app I have, we display charts on 1 page of active admin, and have included the chart library at the top of the view:
= javascript_include_tag "//www.google.com/jsapi", "chartkick"
%h2 History chart
= line_chart participant.linear_chart_payload, curve: false
The script goes in the body, which is not ideal, but it works fine. I don't think there's a need to put CSS in the view itself, as you should be able to use selectors to ensure that the CSS only applies to the view you need it to.

different css for index action in rails 5 bootstrap 4 (single controller)

I am using a specific bootstrap 4 template for my application. This template (cover.css) is specific to the homepage as all the others pages will use a different style.
How can I use cover.css only for the index action?
In my application.css I added #import "cover" can I have this only applied to the index action?
I tried creating two layouts instead: application.html.erb to use it for the application, and a second layout home.html.erb just for the home page. How can I associate cover.css for only the index action and have my dashboard layout and css for the rest of the application?
I am using rails 5 and bootstrap 4 alpha.
There are a few ways to accomplish this.
You can create a layout which includes the cover.css asset, and then only apply the layout for the index action as described here Rails layouts per action?
class MyController < ApplicationController
layout :resolve_layout
# ...
private
def resolve_layout
case action_name
when "new", "create"
"some_layout"
when "index"
"other_layout"
else
"application"
end
end
end
Another option would be to use a single layout and scope your styles.
In views/layouts/application.html.erb Set classes on the body tag like this
<body class="<%= controller_name %> <%= action_name %>">
When rendered it will output
<body class="home index">
Then in your cover.css scope your styles to the .home.index selector
body.home.index h1{
/* this style is only applied on the home/index page */
}
Something like this will work.
<%= stylesheet_link_tag "application", :media => "all" %>
<%= stylesheet_link_tag params[:controller] %>
See the 3rd answer here: How do I use Controller specific stylesheets in Rails 3.2.1?

RoR stylesheet layout view link. What does `:media => all` mean

I have:
<&= stylesheet_link_tag "application", :media => "all" %>
but I am adding a (completely) alternative layout for some of the views in my application, with separate stylesheets. I would like to link the existing layout to only some of the stylesheets, and add others. What do I need to change here?
for this you can create new file in views/layout as similar to your application.html.erb
for example i am creating home.html.erb.Link your all stylesheets and js files in that and finally just add that layout name in your required controller as layout 'home'
You can use separate manifest file and include those manifest file
This answer will help you how to do this
It specifies that your application.css should be loaded when the page is viewed in all media types. It's a CSS property, not a Rails property.
See http://www.w3.org/TR/CSS2/media.html#media-sheets for more details.
You can add a separate layout for whole controller or for specific actions
For example:
in your controller:
layout :resolve_layout
#controller code
...
def resolve_layout
case action_name
when "new", "create", "wait_conformation"
"customer_layout"
else
"producer_layout"
end
end
Here customer_layout & producer_layout are layout files.

how do I call the asset_pipeline for only 1 file?

I'm trying to understand the asset_pipeline.
I basically have all my website-wide code in style.css.scss (which is #imported in application.css.scss)
I also have a few miscellaneous controllers that have code that I split off into a separate file only to be loaded on that page. For example, in my profiles_controller I have profiles.css.scss and profiles.js
in the documentation it says i can conditionally include those by typing:
<%= stylesheet_link_tag params[:controller] %>
and a similar one for javascript_include_tag
The problem is when i view source on any of my pages that dont have a controller stylesheet it is a 404 file not found. I dont want to have 10 blank files for each controller and 10 blank javascript files (those controllers have hardly any extra css or code, so i put it in the main scss file) ... am i doing this wrong?
Note:I have removed include tree from the JS and css files, as i dont want any file in that folder being included
In your application layout file, add yield statements like this to pull in the stylesheets you include as one-offs in different views:
= stylesheet_link_tag "application"
= yield :stylesheets
= javascript_include_tag "application"
= yield :javascripts
Then in each view file where you want to include stylesheets:
= content_for :stylesheets do
= stylesheet_link_tag "controller_name"
= content_for :javascripts do
= javascript_include_tag "controller_name"
This will include those files in only the views you need them in.

conditional loading of stylesheet

I have a site with clients. Every client can have it's own theme and when a user of a certain client is logged in, the company theme must be loaded. In the application.css.scss I have a line like this for every company:
#import "_theme_x.css.scss";
#import "_theme_y.css.scss";
#import "_theme_z.css.scss";
How can I load only e.g. theme_x when a user of company x is logged in and not load theme_y and theme_z? Or is there a better way of doing this? Thanks!
If themes are large, you might want to separate them from the application.css and load them conditionally in your layout. For example, if you have a helper theme_stylesheet in application_helper which returns the name of the theme the client is using:
# application.html.erb
<%= stylesheet_link_tag 'application', theme_stylesheet %>
If they are small, I like namespacing. Leave your application.css as-is, but modify the themes to use a top-level rule on the body. Place a tag on the body to select the theme. The beauty of this is you can dynamically change the theme.
<body class="theme-<%= theme_stylesheet %>">
...
</body>
_theme_x.css.scss
body.theme-x {
...
}
you can do it in this manner like you can check first whose client is login and apply some
layout for him and include diffrent css files for diffrent layout.
Like i do
first i make method in application helper but i can implement layout according user roles you
can do it according clients.
def choose_layout
if is_admin?(current_user) or is_super_admin?(current_user)
'admin'
else
'application'
end
And in controller call it in before filter than layout will be implement according to user
roles
class AdministratorController < ApplicationController
include ApplicationHelper
layout :choose_layout
def index
#user = User.new
#current_user = current_user
end
end
hope you could get the idea.....

Resources