unable to determine if controller based asset exists without .js extension rails - ruby-on-rails

I have added assets for a controller and wants to include them per request.
The problem is that it does not include that assets without writing .js in controller path
The code on layout page is:
<%= controller_specific_js = "#{params[:controller]}.js" %>
<%= javascript_include_tag controller_specific_js if asset_exist?
(controller_specific_js) %>
Helper method:
def asset_exist?(path)
if Rails.configuration.assets.compile
Rails.application.precompiled_assets.include? path
else
Rails.application.assets_manifest.assets[path].present?
end
end
The assets are in admin/popular_schools that are admin/popular_schools.js.coffee
<%= controller_specific_js = "#{params[:controller]}.js" %>
The above line outputs: admin/popular_schools.js and adds it.
URL is: http://localhost:3000/admin/popular_schools
assets.rb:
Rails.application.config.assets.precompile += %w( admin/popular_schools.js.coffee )
production.rb
config.assets.compile = true
How exactly I can run it without specifying .js in "#{params[:controller]}.js" as conventially its is not good.
If I remove .js it does not insert it in assets but if I include it it starts to appear.
Also if I use below code:
<%= controller_specific_js = "#{params[:controller]}" %>
<%= javascript_include_tag controller_specific_js if asset_exist?(controller_specific_js) %>
It does work without specifying .js but if I do not want to include any controllers in assets.rb file they start to output exception that file is not included in the assets.erb but it does included in assets folder and for some reasons I do not want to include them in assets.rb
Any workaround or conventions?

Related

Rails - How to set 1 scss file for 1 view

I can't figure out how make certain .scss files work with certain views. I removed the *= require_tree . from the application.css.scss but I'm not sure where to go from there. The stylesheet_link_tag doesn't seem to recognize .scss files. What tag can I use to import .scss files to views?
I also tried creating a different controller for the different view but after I removed the require_tree the controller doesn't use the .scss file that was automatically generated with it.
In application.css remove *= require_tree.
In application.html add:
<head>
<%= yield :stylesheets %>
</head>
And on every page render:
<% content_for :stylesheets do %>
<%= stylesheet_link_tag "your file" %>
<% end %>
The most important piece you are probably missing is that Sprockets won't serve any asset, mainly the css and js need to be declared in your asset manifest. Quoting the docs:
If you have other manifests or individual stylesheets and JavaScript files to include, you can add them to the precompile array in config/initializers/assets.rb:
Rails.application.config.assets.precompile += ['admin.js', 'admin.css', 'swfObject.js']
Use the expected resulting name (with .css extension) and not the source file (with the .scss extension).
There is a way to organize your assets based on controller.
Rails guide has a section about it.
According to it you can create app/assets/stylesheets/projects.css.scss file for your ProjectsController and include it like this:
<%= stylesheet_link_tag params[:controller] %>
When doing this, ensure you are not using the require_tree directive, as that will result in your assets being included more than once.
Action based stylesheets can be created similarly:
<%= stylesheet_link_tag "#{params[:controller]}/#{params[:action]}" %>
if the scss file is in the root of the asset folder then
add line to your view file
=stylesheet_link_tag 'your_scss_file_name'
in \config\initializers\assets.rb
add this line
Rails.application.config.assets.precompile + =% w (your_scss_file_name.css)

How to add markdown as a preprocessor to the asset pipeline?

I have markdown files in app/assets/md/*.html.md which I would like to precompile with rake assets:precompile.
How can I set the asset pipeline up so that it will use a markdown parser to produce the expected HTML files?
Also, how can I include these precompiled assets directly within my views, such as:
<div>
<%= yield asset("my_markdown_fragment.html") %>
</div>
I have since found the solution. Here is what I did:
Add rdiscount to the Gemfile (rdiscount is a Markdown processor for Ruby):
gem 'rdiscount'
Create the file lib/markdown_preprocessor.rb with these contents:
require 'rdiscount'
class MarkdownPreprocessor < Sprockets::Processor
def evaluate(context, locals)
RDiscount.new(begin;data;end).to_html
end
end
Add the MarkdownPreprocessor to the asset pipeline in the config/initializers/sprockets.rb file (create this file if it does not exist) like this:
require 'markdown_preprocessor'
Rails.application.assets.register_engine('.md', MarkdownPreprocessor)
Add the following line to the config/initializers/assets.rb file:
Rails.application.config.assets.paths << Rails.root.join('app', 'assets', 'md')
Configuration is done now. Here are some other guides and tips:
Place your Markdown files into the app/assets/md/ folder.
The extension of your files end with .md, but I suggest .html.md (since the result is an HTML file).
You can insert <%= ruby %> into your Markdown files when you add the .erb extension. For example, try creating this file app/assets/md/hello.html.md.erb with the following contents:
# Hello <%= "_World_ " * 42 %>
You can access the resulting HTML content in your views and controllers with:
Rails.application.assets[asset_path].to_s.html_safe

How to serve image assets from an Engine in a Rails app

I'm having trouble getting image assets in my engine to render inside the host app.
My host app is capable of grabbing css and javascript from then engine thanks to code like this in the view/layout/application.html.erb file:
<%= stylesheet_link_tag 'my_engine/application', :media => 'all' %>
<%= javascript_include_tag 'my_engine/application' %>
However, I don't know of a similar method for including the images from my engine. Any ideas on how I can get the engine's image files to render in the host app?
Edit:
In my engine's engine.rb file, I've added the images directory to the app's directory like this:
initializer :assets do |config|
Rails.application.config.assets.paths << root.join("app", "assets", "images", "my_engine", "some_subdirectory")
end
and the view has an image tag that looks like this:
<%= image_tag "/my_engine/some_subdirectory/picture.png" %>
but my server logs, I see this:
Started GET "/assets/some_subdirectory/picture.png" for 127.0.0.1 at 2014-04-06 20:11:38 -0500
Served asset /some_subdirectory/picture.png - 404 Not Found (3ms)
ActionController::RoutingError (No route matches [GET] "/assets/some_subdirectory/picture.png"):
You don't need to do this at all because Rails does it for you:
initializer :assets do |config|
Rails.application.config.assets.paths << root.join("app", "assets", "images", "my_engine", "some_subdirectory")
end
Instead, you can reference the images exactly the same way as you would as if they were in the application:
<%= image_tag "your_image.jpg" %>
I'm assuming here that your_image.jpg is at /app/assets/images/your_image.jpg within your engine. If it's in a subdirectory, then:
<%= image_tag "subdirectory/your_image.jpg" %>
There's no need to include the name of your engine in the path unless the file is at some place like app/assets/images/your_engine/your_image.jpg, in which case:
<%= image_tag "your_engine/your_image.jpg" %>
Would be the correct way to do this.
The Engines Guide contains more useful information about engines too.

Use assets in folder only when on page X

I've got a folder of js files that I want to include only when I'm on my dashboard page(or controller).
Can I exclude that folder from my application.js's //= require_tree . file and only include it in my dashboard?
You can have application.js require only some files, rather than the everything-and-the-kitchen-sink approach of require_tree .
For instance, make a directory structure like this:
javascripts/
application.js
special.js
common/
foo.js
bar.js
special/
other.js
Then have application.js only include files in the "common" directory by using
= require_tree ./common
Meanwhile, "special.js" (find a better name, obviously), require everything in "special"
= require_tree ./special
Then you'll have to tell Rails that "special.js" should be pre-compiled by the asset pipeline (if you do use asset precompilation). This is done in config/production.rb, and there's already a commented line there showing to to do it. So just uncomment and edit that line, and you should get:
config.assets.precompile += %w( special.js )
If you don't do this, the precompilation will only look at application.js (the default)
Finally, in the relevant views, you can include the special JS by saying
<%= javascript_include_tag "special" %>
You can just place that at the bottom of the file
You can create another js file - dashboard.js, and include it only for dashboard controller
<% if current_page?(:controller => 'dashboard') %>
<%= javascript_include_tag 'dashboard' %>
<% else %>
<%= javascript_include_tag 'application' %>
<% end %>
In your environments/production.rb just add
config.assets.precompile += %w(dashboard.js)

Asset Precompilation OK, but 404 when trying to get files

Ok so compiling my assets is working fine but when I run:
thin start -e production
none of my javascript or css is loading. My browser is also cancelling the requests to get my assets. I'm not sure why this is but I suspect its because it thinks its 404'ing on them. If you look at the top image you'll see that my application.css file was compiled and stored in my assets folder but when I try to access the file, I'm getting my 404.html file.
What gives!?
Edit:
I was asked to post my view. Here is some of the code in the project:
<% content_for :title, 'Quick Quote' %>
<% content_for :subtotal, get_subtotal %>
<% content_for :stylesheet_includes do %>
<%= stylesheet_link_tag "quote", "jquery-ui-timepicker-addon" %>
<% end %>
<% if #quote.errors.any? %>
<div class="flash alert">
<% #quote.errors.full_messages.each do |msg| %>
<div><%= msg %></div>
<% end %>
</div>
<% end %>
<h1>Quick Quote</h1>
my layout:
<!DOCTYPE html>
<html>
<head>
<title><%= (yield(:title) + " - " unless yield(:title).blank?).to_s + "Online Scheduler Order Taker" %></title>
<%= stylesheet_link_tag "application", "jquery-ui-timepicker-addon.css", :media => "all" %>
<%= yield :stylesheet_includes %>
<%= javascript_include_tag "application" %>
<%= yield :javascript_includes %>
<%= csrf_meta_tags %>
</head>
<body>
code in my production.rb
config.assets.precompile += %w( quote.css jquery-ui-timepicker-addon.css prices.css contact.css )
Top of my application.css.scss.erb:
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the top of the
* compiled file, but it's generally better to create a new file per style scope.
*
*= require_self
*
* require_tree . <- commented out
* require jquery-ui-timepicker-addon.css <- commented out
*/
my entire application.js file
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require jquery-ui-timepicker-addon.js
//= require_tree .
Check your config/environments/production.rb file and add next line to it (if it does not have it yet):
config.serve_static_assets = true
Rails recommends that this setting config.serve_static_assets by default should be disabled i.e. set to false. Here is the default configuration in config/environments/production.rb generated in rails app
Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false
So if you are setting it to true in your local app then that's still fine. But if you are deploying your app on Apache or ngix or anything other than heroku then its not advisable to make config.serve_static_assets=true in your production.rb config file. Here is the documentation in Rails guides.
config.serve_static_files configures Rails itself to serve static
files. Defaults to true, but in the production environment is turned
off as the server software (e.g. NGINX or Apache) used to run the
application should serve static assets instead. Unlike the default
setting set this to true when running (absolutely not recommended!) or
testing your app in production mode using WEBrick. Otherwise you won't
be able use page caching and requests for files that exist regularly
under the public directory will anyway hit your Rails app.
URL - http://guides.rubyonrails.org/configuring.html
Rails 5:
Change config.public_file_server.enabled in production.rb to true or add RAILS_SERVE_STATIC_FILES with any value to env variables.
Reference: https://github.com/rails/rails/pull/18100
Can you put this line in your current environment.rb?
config.serve_static_assets=true
Reference: here

Resources