using Bourbon with wagon ( Locomotive CMS ) - ruby-on-rails

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!

Related

How do I make a Bootstrap sass variable visible to another imported sass file?

I am using bootstrap-sass in a Rails application. So far, everything has worked fine, but I have just tried to import another third-party sass file that uses bootstrap variables and it cannot see them.
In my application.css.scss
*= require bootstrap_local
In bootstrap_local.css.scss
#import "bootstrap";
#import "bootstrap-social";
When I do a page access, I get a Rails error
Undefined variable: "$line-height-computed".
(in .../app/assets/stylesheets/bootstrap-social.scss:11)
The variable needed by bootstrap-social.scss is defined in the previously imported bootstrap file (in fact it's defined in a partial bootstrap/variables that it includes).
As far as I understand, this should work because bootstrap_local is required, which means that everything in it is compiled together in one scope, so everything imported into bootstrap_local is treated as being one large file. Perhaps I have this wrong?
If I throw an #import "bootstrap"; into bootstrap-social.scs then it works fine. But I should not need to do this, so I either doing something wrong or I there is some misconfiguration with my setup.
What do I need to do to fix this?
Gems:
bootstrap-sass-3.1.1.1
sass-rails-4.0.3
System:
Rails 4.0.1
ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-linux]
(Bootstrap Social is a set of social sign-in buttons made in pure CSS based on Bootstrap and Font Awesome.)
The problem described in the question can be resolved by changing the application.css.scss manifest to use import instead of require:
#import "bootstrap_local";
It is also necessary to remove any require_tree . from the manifest because it would otherwise require the same bootstrap_local file because it lies in its path.
On reflection, not having require tree . in the manifest is probably wise because it prevents unwanted files from being included. I only had it there because it's there by default in a new Rails project (the same goes for require_self; it's cleaner not to put that in the manifest).
In reference to the suggestion about prefixing the file with an underscore, this is a good thing to do when the you don't need file, like bootstrap-social in the question, to be a compiled into a separate CSS file. So, I did end up renaming it to _bootstrap-social.scss.

Why Rails Asset Pipeline uses require instead of #import?

If Rails (3, 4) uses SASS for precompile the CSS,
Why uses "require" for default, instead of Sass directive "#import" (http://sass-lang.com/documentation/file.SASS_REFERENCE.html#import)
The same Rails documentation suggest to use "#import" (http://edgeguides.rubyonrails.org/asset_pipeline.html)
As noted in the document you linked to, #import is preferable because Sass variables can be shared between files. But having the Sprockets-provided require directive allows you to include stylesheets from gems or bypass using Sass altogether.
There is usually more than one way to accomplish a task, it’s good to have options. For instance, Javascript has many solutions to dependency management, but the simple Sprockets require is often adequate for simple applications.

Using a Rails Engine to share SASS Mixins across projects

I am trying to build a Rails Engine which serves assets to its host application. Specifically, I would like to be able to do the following:
# Host App's Gemfile
gem 'my-rockin-engine'
And ...
# Host App's application.css
/*
*= require styles
*/
#import 'my-rockin-engine/mixins'
And ...
# Host App's style.sass
.host-app-defined-class-name
+my-rockin-engines-mixin
Where the mixin "my-rockin-engines-mixin" is defined somewhere in the assets of MyRockinEngine.
The problem
I have a chain of #imports from the host app, through the engine. (I'm using #imports due to reasons described here.) Any style definitions that I create inside the Engine's assets are available to the host app. However, none of the SASS mixins I create are available anywhere other than in the same file that the mixin is defined in.
Essentially, I'm wondering if my implementation is not working because either (1) I'm using Engines in a confused way; (2) It is not possible to share mixins between Rails Engines and their host application; (3) There is some aspect of sprockets/rails/compass/sass (#import/require) directives that I am misunderstanding.
Any help would be greatly appreciated! And I can always offer further details should anyone need them.
For posterity, it seems the problem I was having was in the realm of (3) -- described in my question.
Don't try and #import sass files which are named foobar.css.sass. Compass will treat such files as css, since they have to be imported via #import 'foobar.css'. #import foobar will fail because the .css is part of the filename.
So, my problem is solved by ensuring any files I #import use the .sass extension, and don't have .css in the last part of the file name.

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

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

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.

Resources