Rails 3.2 Asset Pipeline + html5shiv.JS in vendors/assets/javascript - ruby-on-rails-3

After reading this post (recommended reading) about not using HTML5Shiv direct from source like (almost) everybody does, I'm trying to include the html5shiv.js in my app using Rails 3.2 Asset Pipeline.
I downloaded both minified and not-minified version of the javascript. The convention tells you to add third-party files into the vendors/assets folder. I have two questions now:
1) Which version (minified or not-minified) should I add to vendors/assets/javascrip folder?
2) Since it's a conditional reference <!--[if lt IE 9]>, how should I call the script?
I don't want to add it to the application.js manifest, because I want to keep it as a separate file and I want to use the condition. I'm kind of lost!
Any help would be very appreciated.
Thanks

You can use the unminified version of the JS if you like, Rails will compress it in production mode through the pipeline.
To keep the shiv as a separate file you can give it it's own manifest by creating a html5.js (or whatever) in your /vendor/assets/javascripts/ directory. In that file require the html5shiv (I assume the manifest and script are in the same dir).
//= require html5shiv
or
//= require html5shiv.min
And then include the manifest in your layout in the conditional block. In HAML something like:
== "<!--[if lt IE 9]>"
= javascript_include_tag 'html5'
== "<![endif]-->"
Remember to restart your app server before testing.

Or you may use directly
/[if lt IE 9]
%script{ src: "http://html5shim.googlecode.com/svn/trunk/html5.js", type: "text/javascript" }

Related

How can you include a javascript files from a CDN in Jasmine?

When using Jasmine in a Rails project, to keep the dependencies consistent in my Jasmine specs, I want to pull jquery from a cdn as is done on the real page. I try to do that like so, in my Jasmine.yml file:
helpers:
- http://code.jquery.com/jquery-1.9.1.js
However, this never works, as when viewing the source of the localhost:8888 I get:
<script src="/__spec__/http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
How do you this correctly?
as answered in https://github.com/pivotal/jasmine-gem/issues/135
I wrote a helper to load external javascripts. It's not the best solution (i would prefer config file use) but it works for me.
var head = document.getElementsByTagName('head')[0];
var jQueryScript = document.createElement('script');
jQueryScript.setAttribute('type', 'text/javascript');
jQueryScript.setAttribute('src', '//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js');
head.appendChild(jQueryScript);
#emrox's answer is correct and works for jasmine 2.0.
However in jasmine 2.1.3 it doesn't. This is due to the fact that when the tests are run(i'm using Chutzpah) "http:" isn't pre-pended to the CDN reference. It is in version 2.0 of jasmine.
The fix I implemented that worked involved the following line of code:
jQueryScript.setAttribute('src',
'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js');
Hopefully this helps someone before they decide to downgrade to 2.0!
Issue 135 made it so you can list CDN entries in your jasmine.yml file. e.g.
src_files:
- http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js
- http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js
- lib/javascript/**/*.js

Rails Production Single JS File Isn't Precompiled?

So I have a file jquery.tmpl.min.js sitting under app/assets/javascripts/ and for whatever reason it's not being found in my production server. After runnings rake assets:precompile it completes without any errors whatsoever. All my other javascript assets get compiled properly and sent to the browser. I don't have any issues on my development server finding this JS file.
I have the following lines in my production.rb file:
config.serve_static_assets = true
config.assets.compile = true
config.assets.precompile += %w( *.js *.css )
Error message:
ActionController::RoutingError (No route matches [GET] "/assets/jquery.tmpl.min.js"):
Edit
According to this issue: https://github.com/rails/rails/issues/3596
Using the javascript_include_tag with something like 'jquery.ba-url.min' wont append the .js extension. Originally I had that but have since changed it to include the .js extension. Still no dice however.
Edit 2
I tried adding //= require jquery.tmpl.min.js to my application.js but now when I attempt to precompile my assets it says it can't find the file.
Edit 3
Tried adding //= require_tree and still it isn't found. This is driving me nuts!
Ok, I found the answer. It turns out Edit 2 was the fix that I was looking for. Problem was that I made the edit on development and commited to my production server using github. However I forgot to add the renamed file to the commit so all my commit ended up doing was deleting the file on the production server.

Using Compass on Heroku: /tmp for stylesheets remotely and locally

I'm currently using Compass with Heroku using this configuration recommended on the Heroku knowledge base. Heroku has a read-only file system, and so the compiled stylesheets need to be stored in /tmp. This works fine remotely on Heroku; locally, however, Rails expects to find stylesheets in /public/stylesheets (when called through = stylesheet_link_tag 'screen.css', :media => 'screen, projection').
In order to solve the problem, I have created symbolic links in /public/stylesheets using ln -s tmp/stylesheets/screen.css public/stylesheets/screen.css and that seems to work.
Is there a way to solve this problem without using symbolic links, perhaps by changing some configuration in Rails? I've poked around without much success.
Here is my config/initializers/compass.rb:
require 'compass'
require 'compass/app_integration/rails'
Compass::AppIntegration::Rails.initialize!
# Required for Heroku:
require 'fileutils'
FileUtils.mkdir_p(Rails.root.join("tmp", "stylesheets"))
Compass::AppIntegration::Rails.initialize!
Rails.configuration.middleware.delete('Sass::Plugin::Rack')
Rails.configuration.middleware.insert_before('Rack::Sendfile', 'Sass::Plugin::Rack')
Rails.configuration.middleware.insert_before('Rack::Sendfile', 'Rack::Static',
:urls => ['/stylesheets'],
:root => "#{Rails.root}/tmp")
And here is my config/compass.rb:
project_type = :rails
project_path = Compass::AppIntegration::Rails.root
# Set this to the root of your project when deployed:
http_path = "/"
# Necessary for Heroku (original commented out:
css_dir = 'tmp/stylesheets'
#css_dir = "public/stylesheets/compiled"
sass_dir = 'app/views/stylesheets'
environment = Compass::AppIntegration::Rails.env
Any help would be greatly appreciated.
I was actually just about to set up Compass with our Rails application, which is hosted on Heroku, so cheers for giving me an excuse to work through this. :)
The answer is simple:
Modify 'config/compass.rb':
project_type = :rails
project_path = Compass::AppIntegration::Rails.root
http_path = "/"
environment = Compass::AppIntegration::Rails.env
if environment == 'production'
css_dir = "tmp/stylesheets"
sass_dir = "app/views/stylesheets"
else
css_dir = "public/stylesheets"
sass_dir = "app/stylesheets"
end
Then modify 'config/initializers/compass.rb':
require 'compass'
require 'compass/app_integration/rails'
Compass::AppIntegration::Rails.initialize!
require 'fileutils'
FileUtils.mkdir_p(Rails.root.join("tmp", "stylesheets"))
environment = Compass::AppIntegration::Rails.env
if environment == 'production'
Compass::AppIntegration::Rails.initialize!
Rails.configuration.middleware.delete('Sass::Plugin::Rack')
Rails.configuration.middleware.insert_before('Rack::Sendfile', 'Sass::Plugin::Rack')
Rails.configuration.middleware.insert_before('Rack::Sendfile', 'Rack::Static',
:urls => ['/stylesheets'],
:root => "#{Rails.root}/tmp")
end
... and voila, you're good.
ok, I'm a big heroku and compass fan myself so i've been through this many times
Heroku's docs, whilst giving correct information, provide poor advice in this instance.
When using compass, the best thing to do, 99.999% of the time is turn it off in production mode.
This means that you compile your stylesheets on your development machine and then add them to your git repo before pushing to heroku.
You will suffer a reasonably sizeable performance hit if you allow compass to compile on the server.
So here's what I do:
You should have a config.ru file at the base of your app. Open it and add the following:
require 'sass/plugin/rack'
use Sass::Plugin::Rack
Sass::Plugin.options[:never_update] = true
You can then remove quite a lot of the code from your initializer (especially the part where you unload Sass::Plugin::Rack). Additionally you will want to remove the if statement from compass.rb in config folder
Think about it, why would you want Sass to compile a stylesheet on the server? It just eats up processing power. Hope this helps,
EDIT::
PS - I should add that you will need to run compass watch from the command line now in order to get your stylesheets to compile in your dev environment
The recommended Heroku configuration will also work locally.
Removed the second 'Compass::AppIntegration::Rails.initialize!' from config/initializers/compass.rb, you only need it once.
Ensure your scss files are in 'app/views/stylesheets'
On both local and production servers the stylesheets will be compiled to tmp/stylesheets, and a request to /stylesheets will resolve to tmp/stylesheest. No need for two separate configurations.

How do I get the root directory of a gem in the Rspec tests for my Rails project?

I've got a gem, we'll call it ToastMitten, which I'm including in one of my Rails apps. I'm writing some tests for ToastMitten in which I need to load a file, and I want to specify a path from the root of the gem.
I just tried using Rails.root.to_s, but that gives me something like /Users/me/projects/toastmitten/spec/dummy. I would have expected that path to end at toastmitten/.
What am I doing wrong?
Rails.root.parent.to_s
If it always gives back your dummy Rails app, just move up to the parent.
It looks like you are using a Rails engine (generated with enginex, hence the dummy app in your spec folder). If you need to require a file in your test using an absolute path, you can use the following:
file = File.expand_path(File.join(File.dirname(__FILE__), 'path', 'to', 'file.ext'))
root = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
Can you be more specific on where you are trying to require this file?
Also, The root example may require more ..'s.

Multiple public folders, single rails installation

I have a rails application I would like to use for multiple sites, each with different designs.
I would like to change the rails installation /public directory to something else (dynamically eventually). However, I have run into a problem (bug?) changing directories...
In my application.rb file I change the paths.public path to something other than "public" (let's say "site_one"). Here is the code:
puts paths.public.paths
paths.public = "site_one"
puts paths.public.paths
The two "puts" commands are for debugging. Now run "rails s" and you will see:
/home/macklin/app/public
/home/macklin/app/site_one
This verifies the path is changed correctly. However, shortly afterward, rails throws the following error (let me know if you need the full trace):
Exiting
/usr/lib/ruby/gems/1.8/gems/railties-3.0.3/lib/rails/paths.rb:16:in `method_missing': undefined method `javascripts' for #<Rails::Paths::Path:0x7f422bd76f58> (NoMethodError) from /usr/lib/ruby/gems/1.8/gems/actionpack-3.0.3/lib/action_controller/railtie.rb:47
My guess is it cannot find the javascripts directory even though it is clearly sitting in the "site_one" folder.
Does anyone know why I am getting this?
I know this question is pretty old, but I think I found an answer for this in Rails 4.2.
You just simply have to put this line in your config/application.rb:
middleware.use ::ActionDispatch::Static, "#{Rails.root}/another_public_folder_name", index: 'index', headers: config.static_cache_control
This makes all files in /another_public_folder_name to be served by Rails.
This is the way Rails use to setup the standard /public folder. I found it checking the sources:
https://github.com/rails/rails/blob/52ce6ece8c8f74064bb64e0a0b1ddd83092718e1/railties/lib/rails/application/default_middleware_stack.rb#L24
Duh. Just add 2 more rules for stylesheets and javascripts (I guess they get wiped when you change the parent path)
paths.public.stylesheets = "site_one/stylesheets"
paths.public.javascripts = "site_one/javascripts"