I am little confusing that I am using bootstrap in rails project. I want use bootstrap in admin areas and not in home. But It doesn't work. I have added #import "bootstrap" into stylesheet/admin/admin.css.scss - not working. But If I add this into stylesheet/application.css.scss it's working, but it's override all other css styles and alos apply on home page which I don't want.! Project dir Image.
I have added javascript and css include tag into views/layout/admin.html.erb same as application.html.erb
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
Any another way to include only admin/*.css files into admin.
In your stylesheet folder create an admin.css.scss file with the following content:
/**
* admin.css.scss
*
*= require_self
*= require_tree ./admin
*/
Then, in your admin layout you can include just the newly created admin.css.scss stylesheet, like this:
<%= stylesheet_link_tag "admin.css.scss", :media => "all" %>
It will act as a loader of all css/scss files in the "admin" subfolder.
The answer of #svilenv is correct but you need also add the assets on config/environments/production.rb:
config.assets.precompile += %w[admin.css]
Related
In a rails 3.2 app, I would like to check for the existence of a javascript file in the asset pipeline before including the javascript_include_tag in a file. Something like:
<% if javascript_file_exists? %>
<%= javascript_include_tag "#{controller_name}_controller" %>
<% end %>
I would like to do this so that the absence of a javascript file will not result in an error. Is there a way to do this?
A more Rails way is to use a helper. This allows you to check for a coffeescript or a javascript version of a file:
def javascript_exists?(script)
script = "#{Rails.root}/app/assets/javascripts/#{params[:controller]}.js"
File.exists?(script) || File.exists?("#{script}.coffee")
end
Then you can use it in your layout:
<%= javascript_include_tag params[:controller], :media => "all" if javascript_exists?(params[:controller]) %>
You can do the same with your CSS:
-- helper --
def stylesheet_exists?(stylesheet)
stylesheet = "#{Rails.root}/app/assets/stylesheets/#{params[:controller]}.css"
File.exists?(stylesheet) || File.exists?("#{stylesheet}.scss")
end
-- layout --
<%= stylesheet_link_tag params[:controller], :media => "all" if stylesheet_exists?(params[:controller]) %>
EDIT: updated #javascript_exists?
I have recently made some changes to my javascript_exists? helper:
def javascript_exists?(script)
script = "#{Rails.root}/app/assets/javascripts/#{script}.js"
extensions = %w(.coffee .erb .coffee.erb) + [""]
extensions.inject(false) do |truth, extension|
truth || File.exists?("#{script}#{extension}")
end
end
call it in the application layout:
<%= javascript_include_tag params[:controller] if javascript_exists?(params[:controller]) %>
This will now handle more extensions and use an inject to determine if the file exists. You can then add a bunch more extensions to the extensions array, as needed for your app.
EDIT DEUX: Updated #stylesheet_exists?
Same, but for stylesheets:
def stylesheet_exists?(stylesheet)
stylesheet = "#{Rails.root}/app/assets/stylesheets/#{stylesheet}.css"
extensions = %w(.scss .erb .scss.erb) + [""]
extensions.inject(false) do |truth, extension|
truth || File.exists?("#{stylesheet}#{extension}")
end
end
EDIT Last (probably): DRY it up
def asset_exists?(subdirectory, filename)
File.exists?(File.join(Rails.root, 'app', 'assets', subdirectory, filename))
end
def image_exists?(image)
asset_exists?('images', image)
end
def javascript_exists?(script)
extensions = %w(.coffee .erb .coffee.erb) + [""]
extensions.inject(false) do |truth, extension|
truth || asset_exists?('javascripts', "#{script}.js#{extension}")
end
end
def stylesheet_exists?(stylesheet)
extensions = %w(.scss .erb .scss.erb) + [""]
extensions.inject(false) do |truth, extension|
truth || asset_exists?('stylesheets', "#{stylesheet}.css#{extension}")
end
end
Although I know about the assets pipeline and the manifest in application.js, my approach is to keep app's "essential" javascript in application.js and load only the specific javascript for each controller using
<%= javascript_include_tag "application" %>
<%= javascript_include_tag controller_name if File.exists?("#{Rails.root}/app/assets/javascripts/#{controller_name}.js") %>
at the end of my application.html.erb before the </body>
I know that causes the browser to issue one more request to get the controller specific javascript but perhaps after the first request, that javascript will be cached by the browser.
I know this is a pretty old question, but I would suggest using the find_asset function. For Rails 4 you could do something like:
<%= javascript_include_tag params[:controller] if ::Rails.application.assets.find_asset("#{params[:controller]}.js") %>
Custom ViewHelpers to the Rescue!
Add this to your ApplicationHelper:
module ApplicationHelper
def controller_stylesheet(opts = { media: :all })
if Rails.application.assets.find_asset("#{controller_name}.css")
stylesheet_link_tag(controller_name, opts)
end
end
def controller_javascript(opts = {})
if Rails.application.assets.find_asset("#{controller_name}.js")
javascript_include_tag(controller_name, opts)
end
end
end
and you can use them like this in your application.html.erb:
<%= controller_stylesheet %>
<%= controller_javascript %>
Note: This works with all .js, .coffee, .css, .scss even though it just says .css and .js
In Rails3.2 all what you need is to write the list of your js files at the top of application.js file. For example,
//=require jquery.min
//=require jquery_ujs
//=require general
If one of these files don't really exists (btw put them at app/assets/javascripts) - not a problem, no errors will be shown.
Catch the error:
#/app/helpers/application_helpers.rb
def javascript_include_tag_if_assets(*args)
javascript_include_tag(*args)
rescue Sprockets::Rails::Helper::AssetNotFound
''
end
Alternatively, since this asks to check before using the method, javascript_include_tag uses javascript_path so you might as well use it to check and then catch that error. This works for all javascript-like assets. For css-like assets, use stylesheet_path.
#/app/helpers/application_helpers.rb
def javascript_include_tag_if_assets(*files, **opts)
files.each { |file| javascript_path(file) }
javascript_include_tag(*files, **opts)
rescue Sprockets::Rails::Helper::AssetNotFound
''
end
secure a specific /assets file from direct access in routes or else somehow?
I have inside my assets like fronted.css and backend.css
This backend css file I would to disable direct access from URL so It can only be loaded from inside my backend_controller.rb.
Is this possible somehow?
In production Rails don`t control assets, this is work for webserver. You can only hide them by excluding from public part of site.
You can use different layouts for frontend and backend or inject some data for custom actions.
Layouts way:
In backend_controller.rb:
class BackendController...
layout 'backend' #you can use :only or :except parameter if you need
...
end
In /your_app/app/assets/stylesheets create backend.css and folder 'backend', move all your backend stylesheets in 'backend' folder and in backend.css insert this:
/*
*= require_self
*= require_tree ./backend
*/
Create in /your_app/app/views/layouts file backend.html.erb. This is your backend layout. Insert there <%= stylesheet_link_tag "backend" %>
Dont forget to remove from /your_app/app/assets/application.css line *= require_tree .(this directive recursive including all files in /your_app/app/assets/stylesheets and your backend.css too).
If you need to require some files or directories use *= require file_name_without_extension or *= require_tree ./directory_name
Injecting way:
In /your_app/app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<%= stylesheet_link_tag "application", :media => "all" %>
...
<%= yield :my_custom_css %>
</head>
...
In any file you need your custom stylesheet(e.g. /your_app/app/views/categories/new.html.erb):
<% content_for :my_custom_css do %>
<%= stylesheet_link_tag 'backend' %>
<% end %>
And remove *= require_tree . from /your_app/app/assets/application.css or your custom css file will be included in application layout
content_for documentation
How can i add multiple css files in rails project ?
I do,
<%= stylesheet_link_tag :cssone %>
Now i need to add more css file.
There are some method to achieve this. First of all, you can specify each manually :
<%= stylesheet_link_tag "first.css" %>
<%= stylesheet_link_tag "second.css" %>
<%= stylesheet_link_tag "third.css" %>
Then, you can wrap those 3 lines in a single one :
<%= stylesheet_link_tag "first.css", "second.css", "third.css" %>
Also, if you want to include all of your stylesheets in the dedicated rails folder (/public/stylesheets/), you can do :
<%= stylesheet_link_tag :all %>
If you have subfolders in the dedicated folder, you have to include the :recursive option
<%= stylesheet_link_tag :all, :recursive => true %>
<%= stylesheet_link_tag :cssone, :csstwo, and so on... %>
In your (assets/stylesheets)
Add your multiple css file let us take eg-a.css,b.css and c.css
NOW
In application.rb write
<%= stylesheet_link_tag "first.css", "second.css", "third.css" %>
I have a problem very similar to this one: rails 3 - link_to to destroy not working
But delete/destroy links do not work; I simply get redirected to the show page of the object. When I make a button for delete, it all works fine. But I'd like to understand why. Does anyone know?
I seems to be related to some .js files I am using/calling.
<!-- This link doesn't work -->
<%= link_to('Delete', post, :confirm => 'Are you sure?', :method => :delete) %>-->
<!-- This button does work -->
<%= button_to "delete", post, :method=>:delete, :class=>:destroy, :confirm => 'Are you sure?' %>
Post Controller
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to(posts_url) }
format.xml { head :ok }
end
end
UPDATE
After doing some further research it seem that everyone else having a similiar issue has included the following jquery library:
<script type="text/javascript" src="/javascripts/dragdrop.js"></script>
But I still don't know what the issue is...
LOG
Started GET "/posts/7" for 127.0.0.1 at Tue Jul 12 08:34:06 -0400 2011
Processing by PostsController#show as HTML
Parameters: {"id"=>"7"}
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = 7 LIMIT 1
SQL (0.2ms) SELECT COUNT(*) FROM "comments" WHERE ("comments".post_id = 7)
Rendered posts/show.html.erb within layouts/application (116.5ms)
HTML generated
Delete
UPDATE: I've found that removing <script type="text/javascript" src="/javascripts/jquery-1.5.1.min.js"></script> fixes my problem. But I don't understand why. Is there a known conflict between jquery1.5.1 and rails 3.0.7?
Make sure you include these in your application layout:
<%= javascript_include_tag(:defaults) %>
<%= csrf_meta_tag %>
In my case adding
<%= javascript_include_tag(:defaults) %>
did not work. However explicitly defining java script files did the trick
<%= javascript_include_tag 'prototype' %>
<%= javascript_include_tag 'application' %>
Not sure yet why :defaults tag didn't work...
Rails will automatically load jquery for you if you have jquery-rails gem loaded via your Gemfile (this is the default rails configuration). It is then loaded via:
<%= javascript_include_tag(:defaults) %>
Have a look at app/assets/javascripts/application.js for the code that tells rails to add jquery via assets:
//= require jquery
//= require jquery_ujs
By trying to load another copy of jquery via this line:
<script type="text/javascript" src="/javascripts/jquery-1.5.1.min.js"></script>
You have caused a clash of jquery instances, the effect of which will be that neither will work.
I have only a single page that requires jquery ui in my entire application. How can conditionally include the javascript files in that single page?
I believe in Rails 2 I could use: (in application.html.erb)
<%- if controller.controller_name == "posts" && controller.controller_action == "new" -%>
<%= stylesheet_link_tag 'jquery-ui-1.8.13.custom.css' %>
<%= javascript_include_tag 'jquery-ui-1.8.13.custom.min.js', 'autocomplete-rails.js' %>
<%- end -%>
But controller.controller_action throws an undefined method error. And after looking at the API, it looks like it's been removed?
Maybe it would be best to remove the conditional from application.html.erb altogether and just put it at the top of posts/new.html.erb ?
I would avoid delegating responsibility for this to your application layout. If you don't need jQuery UI on more than a single view, you are best off letting the view handle that. The following let's you do just that while still keeping your output HTML clean and sensible (ie. not putting JS all over the place willy nilly).
In your layout (application.html.erb):
<head>
<title>Foo Bar</title>
<%= yield :page_specific_assets %>
</head>
In your view that requires jQuery UI (posts/new.html.erb):
<% content_for :page_specific_assets do %>
<%= stylesheet_link_tag 'jquery-ui-1.8.13.custom.css' %>
<%= javascript_include_tag 'jquery-ui-1.8.13.custom.min.js', 'autocomplete-rails.js' %>
<% end %>
Note: despite convention, putting unnecessary javascript in the <head> degrades performance.
I believe it's:
controller.action_name