What is the best method for storing SASS generated CSS in your application and source control? - ruby-on-rails

If you are using HAML and SASS in your Rails application, then any templates you define in public/stylesheet/*.sass will be compiled into *.css stylesheets. From your code, you use stylesheet_link_tag to pull in the asset by name without having to worry about the extension.
Many people dislike storing generated code or compiled code in version control, and it also stands to reason that the public/ directory shouldn't contain elements that you don't send to the browser.
What is the best pattern to follow when laying out SASS resources in your Rails project?

The compass framework recommends putting your sass stylesheets under app/stylesheets and your compiled css in public/stylesheets/compiled.
You can configure this by adding the following code to your environment.rb:
Sass::Plugin.options[:template_location] = {
"#{RAILS_ROOT}/app/stylesheets" => "#{RAILS_ROOT}/public/stylesheets/compiled"
}
If you use the compass framework, it sets up this configuration for you when you install it.

I always version all stylesheets in "public/stylesheets/sass/*.sass" and set up an exclude filter for compiled ones:
/public/stylesheets/*.css

Honestly, I like having my compiled SASS stylesheets in version control. They're small, only change when your .sass files change, and having them deploy with the rest of your app means the SASS compiler doesn't ever need to fire in production.
The other advantage (albeit a small one) is that if you're not using page caching, your rails process doesn't need to have write access to your public_html directory. So there's one fewer way an exploit of your server can be evil.

Somewhat related, but it's a good idea to regenerate your CSS during your capistrano deployments. This callback hook does just that:
after "deploy:update_code" do
rails_env = fetch(:rails_env, "production")
run "#{release_path}/script/runner -e #{rails_env} 'Sass::Plugin.update_stylesheets'"
end
Update: This should no longer be necessary with modern versions of Haml/Sass.

If I can manage it, I like to store all of my styles in SASS templates when I choose HAML/SASS for a project, and I'll remove application.css and scaffold.css. Then I will put SASS in public/stylesheets/sass, and add /public/stylesheets/*.css to .gitignore.
If I have to work with a combination of SASS and CSS based assets, it's a little more complicated. The simplest way of handling this is to have an output subdirectory for generated CSS within the stylesheets directory, then exclude that subdirectory in .gitignore. Then, in your views you have to know which styling type you're using (SASS or CSS) by virtue of having to select the public/stylesheets/foo stylesheet or the public/stylesheets/sass-out/foo stylesheet.
If you have to go the second route, build a helper to abstract away the sass-out subdirectory.

Related

using Bourbon with wagon ( Locomotive CMS )

Is it some possible way to make work Bourbon with wagon of Locomotive CMS ?
I added a bourbon and neat gems to Gemfile of wagon but after bundle install and starting server i got this :
File to import not found or unreadable: bourbon.
Load paths:
/Users/alex/workspace/locomotive-test/public/stylesheets
/Users/alex/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/compass-0.12.2/frameworks/blueprint/stylesheets
/Users/alex/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/compass-0.12.2/frameworks/compass/stylesheets
Compass::SpriteImporter
I have found that getting Locomotive to work with Bourbon (or Susy or any addon SASS gem) is a two-stage problem. First, the resources must be loaded correctly in the Wagon gemfile, and then they must be #imported in every dependent file to compile correctly when pushed to the Engine.
To get Bourbon to import correctly into Wagon (1.5.1), add Bourbon to the gemfile in the :misc group per the sample pattern:
group :misc do
# Add your extra gems here
gem 'bourbon', require: 'bourbon'
end
Then, just run $ bundle install and it should work fine. I found that I didn't need to do $ bourbon install and have the actual .css files in my public/stylesheets folder. The gem was enough for my Wagon instance.
Pushing the site to Engine, however, can prove tricky. Wagon will compile the SASS files in an arbitrary order on push (reference: LocomotiveCMS Google Group). Consequently, the best DRY rails practice of having all your #import calls in one main sass file, and referencing only that file in a top-level application.css file won't work here:
./public/stylesheets
-application.css #requires self and main
-main.scss #imports all other stylesheets, normally where we'd #import 'bourbon'
/other_stylesheets
-variables.scss
etc. etc.
On push, Wagon won't understand that main.scss #imported Bourbon ahead of all other resources. So, it will usually fail with 'undefined mixin...'
To solve that, I still put variables.scss, mixins.scss, etc. in a folder (./public/stylesheets/base/ for instance) and call #import for those resources on every page specific stylesheet (posts.scss, etc.). In addition, any stylesheet that uses a Bourbon, Neat, Susy, whatever mixin has to call #import on that gem reference and the mixins and the variables... it has to be repeated in each dependent sheet.
./public/stylesheets
-application.css # requires self and main
-main.scss # imports all other stylesheets, normally where we'd #import 'bourbon';
/other_stylesheets
-variables.scss # might #import 'font-awesome';
-mixins.scss # #import 'bourbon'; #import 'variables';
etc. etc.
Unfortunately, this is NOT very DRY coding. In fact, there's probably a lot of bloat and redundancy that can be eliminated. So far, it's the most reliable method I've found for pushing my Wagon site to the Engine using these gems. That being said, if you're looking for a quick fix, rather than identifying each resource to #import for each page, you could make an import.scss stylesheet that calls Bourbon, Neat, what-have-you and just #import that import.scss resource into every other sheet.
The final catch (famous last words!), is that the Engine won't accept .scss or .sass files, despite the documentation. Pre-processor stylesheets have to be prepended with .css:
main.scss => main.css.scss
Otherwise, the Engine kick back an error "you are not allowed to upload..."
Hope that helps!
UPDATE:
I realized a couple weeks after posting this that the reason for the Sass troubles in Locomotive vs. other Rails apps: I was using old sprockets syntax in my application.css file.
So, the best method is to make as many Sass sheets partials as possible (prepend your filenames with an underscore -> _example.css.scss). Then, change the application.css to a Sass sheet -> application.css.scss. Finally, don't use any *= require calls like we used to with Sprockets. Instead, we can and should use the Rails best practice of Sass #import calls. You can even glob your partials in subfolders, if so inclined. The reason is, Locomotive installs sass-sprockets and sass-rails gems by default. These gems enable #import in the application.css.scss file with sprockets/asset pipeline. By using Sass partials for subsequent stylesheets, the compilation for application.css.scss will have its own domain and call the partials into it, instead of compiling each subsequent sheet in its own domain. Otherwise, you would probably see wagon push failing with 'unknown mixin...' on the first sheet outside of the main application sheet. If you order your partials in the correct order of dependency (which file does every sheet need? That goes first...), this method also has the added benefit of keeping your compiled application stylesheet very DRY.
Cheers!

How to tell Rails to not clean some assets in the public folder

The issue here is that I have Bootstrap on production looking for the fonts at:
assets/spree/fonts/glyphicons-the-file-name.something
When in development mode, it looks for these assets in:
fonts/glyphicons-the-file-name.something
So what I did was I added the fonts folder into public and it all worked. I did the same for production. You can guess that I'm now dealing with a rails assets:clean issue that must be running and removing the files, hence not allowing them to appear.
Is there a way to tell Rails to not clean the files in assets/spree/fonts?
I'm assuming you installed the bootstrap files manually?
If you instead use a gem such as the following, then you won't have to worry about these issues:
gem "bootstrap-sass"
Alternatively, you should be installing everything into your vendor directory. As you've found you'll then have issues with any linked assets within these files. The correct fix for this would be to edit the bootstrap source to use the correct asset_path helpers.
Obviously that's quite a bit of maintenance overhead when you get round to doing the next bootstrap update.
I'd take a look at the bootstrap-sass gem, even if you decide not to use it.

How to add wrapbootstrap (made with twitter bootstrap) themes to rails application

The website https://wrapbootstrap.com/ has themes which were made using Twitter Bootstrap. Each of these themes include different versions of Twitter Bootstrap along with other various libraries and versions (jquery, fontawesome, etc...)
How do I add these themes to my existing Rails app? What are the steps?
I'm especially curious about the conflicts that may arrise if I'm already using a different version of jquery, twitter bootstrap, fontawesome, and others (as declared in the Gemfile).
Thank you
You can add the css from the theme you purchased from wrapbootstrap to your assets > application.css.scss file. And use the html tags that came with the theme in your rails app views so that the css styling is applied.
Also, I would recommend using gem 'sass-rails' to import the standard bootstrap styling.
Here's a tutorial to get you started with adding bootstrap to a rails app. Adding the theme css and html tags is up to you.
http://railscasts.com/episodes/328-twitter-bootstrap-basics?view=asciicast
I did this for few of the projects, I agree with majorly what Mike has answered above. Here are some of the gotchas I saw.
We started as a standard project on Rails all our views dynamic(Ember)/static were based on Bootstrap CSS. When major internal pages were up and functionality demonstrated we focused on landing pages. By this time we had the gems for bootstrap, fontawesome added to our Gemfile.
So one of the thing is to remove these gems "bootstrap", "fontawesome" from Gemfile. Include these as part of your wrapbootstrap dump.
Also as you progress with integration you may realize that a lot of common code is being repeated, its in your best interest to split the page components: headers, footers other things as partial Rails views. It severely saves the editing effort.
Another thing I found extremely useful to keep every thing up while you are still in integration stage, is to split your CSS/JS includes for pages imported from wrap bootstrap and pages you already have. So if you intend to migrate all existing pages into new theme scraping your CSS, then it can be merged in stages, otherwise you can let them co-exist.
You have to add new entries in routes.rb, controller calls to support the pages if you don't have them already. Likes of about, contactus, team etc. etc.
And if you use something like Ember/Backbone then you have to manage the co-existence of single pager app in some pages which may or may not be linked to the Wrapbootstrap pages.
This was all the things I had to take care off when I integrated the wrapbootstrap theme on top of Rails-EmberJS app.
Interesting timing as I just had to do this myself. I'm still fairly new to Rails so this might not be the best solution, but here's how I got it working ...
Note: every theme is different so this may not be a one size fits all approach.
1) My theme was built with Middleman and it was expecting to run stand alone or on a Sinatra instance.
2) In order to get the theme up on Rails, I had to add the compass gem, the sass gem, the sass-rails gem, and the compass-rails gem to work properly. I'm assuming you can install these (if required for your theme).
3) Assuming you have a Rails app ready to roll, go into your assets directory and backup your .js, .css, and all fonts and images. Place your theme asset files in the appropriate place.
4) Now do the same with your view layer. You may have a partials and/or pages folder which you can place in the views directory. You'll want to put application.erb.html and any navigation files in the layouts folder under the views directory. Again, make sure you back up your original files first.
5) If your theme was designed for Sinatra, you may have a Config.rb file. I moved the logic from this file into my config/environment.rb file. I was the least confident with this step. Other Rails devs can chime in if there is a better location.
6) Start your server up. You may encounter some exceptions but this is to be expected.
7) Take a look at your old app/assets/javascripts/application.js file and compare it to the new file. Ensure that the new file has the jquery ujs library included //= require jquery_ujs . Without this bit of magic your PUT and DELETE HTTP verbs won't work properly.
8) Path adjustments. My theme had the Font Awesome library included. In order to get it to work, I had to adjust the reference paths at the top of the font-awesome.scss file.
9) Finally, you'll need to debug the newly added code in the environment.rb file. The Sinatra developer was doing a lot of Route magic to adjust the navigation display. This wasn't porting over well to my environment. I removed many of these calls from my navigation template files. Once complete, my newly skinned app was up and running! Good luck.
make sure that while installing twitter bootstrap you should add following gem into your Gemfile under "group :assets"
gem 'therubyracer'
gem 'less-rails'
gem 'twitter-bootstrap-rails'
then run bundle command.
Now, the theme "file_name.css" (file_name could be any) that u have downloaded just add it into "stylesheets" folder under app->assests->stylesheets
then open your application.css file in same folder there you will see
*= require_tree.
replace this line with
*= require "file_name.css"
NOTE: Don't forget to re-compile your assets or simply delete the content of your tmp/cache folder.
save it and reboot your server. it will apply youe new theme.
Watch this training course which guide you to do so in detail and from scratch.
http://pluralsight.com/training/courses/TableOfContents?courseName=getting-started-aspdotnet-mvcservice-stack-bootstrap

Enforcing one-to-one matching of sass and css files

I'm using Jammit to package assets and Sass to generate stylesheets in a Rails 3 app. There are around 35 stylesheets for different site components and all are individually listed in our Jammit config. I would like to get to something based more on convention, ie:
stylesheets:
common:
- public/stylesheets/application.css
- public/stylesheets/components/*.css
- public/stylesheets/pages/*.css
The only hurdle I am running into is that I can't find a way to enforce a one-to-one mapping between sass files and css files. The above approach would remove the need to mess with the Jammit config and would automatically add new css files to the site, but if I were to remove a sass file the CSS file would still exist and would still be in our common package. CSS files are ignored in the working tree. Any way to tell Sass to remove CSS files with no template or do I have to add our CSS files to the repo? Is there another option?
Since the CSS files are automatically generated, you can safely just delete the whole directory if you ever want to clean it, and then have Sass regenerate them.

Sass - can it be compiled at runtime?

I've seen that certain Rails CMSes (like Radiant) have plugins that essentially compile Sass when a page is accessed. Is there a way to do this in a regular rails app? Is doing so performant? Basically, I'm looking at a way to remove the extra step of running Compass to compile my stylesheets.
I've not used compass specifically but there looks like there's a production flag so files are compiled - I couldn't imagine they'd build it to recompile per request in production, Radiant compiles it's css on Application startup and if you then commit those generated CSS files it doesn't try to generate them again AFAIK.
http://compass-style.org/docs/tutorials/production-css/
Sass and Compass automatically integrate with Rails. If you're using Rails 3, all you have to do is add gem "haml" to your Gemfile and all .sass and .scss files in public/stylesheets/sass will get compiled to .css files in public/stylesheets.
Compile per request? I think it could be a hit for performance. You should definitely use a caching strategy in that case. So that it compiles the stylesheet only if it is not in the cache.
You could create a helper method setup_stylesheet that will take care of setting up the css stylesheet. You call this method on the application layout.
setup_stylesheet will check if the css stylesheet is on the cache, and if it is there then use it. If it is not, then compile it.
Another approach:
You could set up an initialiser that will call Compass to compile your SASS stylesheets when the App is launched.
Is doing so performant?
There will be a massive performance hit when compiling at run-time.
As Nex3 (author of Sass gem) pointed out on another forum, there's no need any need to run compass watch.
I strongly advise putting the following into production.rb: Sass::Plugin.options[:never_update] = true - this is especially important if you're on Heroku. (you could also do this in your rack file, where you can also specify other options
Hmm, good luck

Resources