Angular + .nghaml template: Referencing Precompiled Image Assets - ruby-on-rails

I'm using .nghaml for my templates and using the following gems for Angular integration:
gem 'angularjs-rails'
gem 'angular-rails-templates'
My Rail view layouts are name.html.haml and using image_tag within them works fine. On production I can see the images.
In contrast, in my Angular templates (assets/template) with their .nghaml extension I can not use Rails helper image_tag and a direct reference does not work
%image(src="assets/sample_image.png")
The direct reference works locally, but on production images don't render.
This person (Rails Image assets in Angular Directive and template) had a similar issue, but using
%img(ng-src='assets/sample_image.png')
worked locally but not in production. And attempting to use image-url results in the error of undefined method (just as image_tag) because none of the Rails helpers seem to be working in the .nghaml extension.
The images that are working (Rails views with image_tag helpers) are referencing the precompiled assets which have their names changed with the addition of a md5-hash (based on the first linked article), but I'm having issues figuring out how to tell the nghaml templates what the new precompiled assets are called without a Rails helper method.
I ran into this issue with helpers a few months ago (Rails App to Angular: HAML + Rails Helpers) and didn't find a solution, but only recently needed to get images into nghaml templates rather than just creating what I needed with CSS.
I'm currently planning to just move the angular templates back to erb if I can't get this figured out, but if there are alternatives (or solutions) I'm unaware of, I'd love to hear them.

The solution proposed in the post Rails App to Angular: HAML + Rails Helpers will allow you to use the helpers (including the image_tag helper) in your haml files when generating the client-side html files.

One issue: According to the official repo for the angular-rails-template library, the .nghaml extension is no longer supported. You have to rename it to .haml
The bigger issue is that you're using Rails to serve a single-page JS app. There's no need for this, you can serve the site using nginx or Apache and control the caching and do cache busting there (nginx & apache cache busting tutorial)
If you're using Rails for the REST API, it should be de-coupled from your frontend AngularJS app.
If you're trying to do some fancy stuff in the templates aside from the cache busting, you should be doing it in JS and plain HTML. It's weird and strange but AngularJS and other frontend MVC/MVVM frameworks are different beasts compared to Rails and Django and the server-side MVC frameworks.

Related

Rails 5 Use Bootstrap CDN without gem

I'm starting a Rails 5 application with Bootstrap 3, I'm confused whether to go with gems like Bootstrap-Sass or use CDN from MaxCDN to rails application.css/js file. I don't plan to modify bootstrap styles, is there any added benefit in using gems other than modifying/mixin.
Using CDN versions should perform better than of gem ?
If I use CDN method there is added benefit of not loading styles/script if user already has it locally in browser ?
Is there any cons for using CDN links in Rails ?
I wouldn't say that there are any cons per se but there are subtle differences.
As you already pointed out, there's the advantage that - if it's a "popular" CDN - users may indeed not need to download the file. But that's a big "if".
On the other hand, a CDN can track users to your site because the resource requests contain a Referer header.
Personally my suggestion would be to serve all local assets via a CDN of your choice, configured via asset host as described in section 4.4.1 of the guides.
In that setup, you'll have the advantage of speedy asset delivery (no hit against your application server) and full control over the assets delivered.

Why can't I add a plain link tag in Rails4 App

Why is it so forbidden to add line like <link href="/assets/stylesheets/bootstrap/bootstrap.css" rel="stylesheet"> in my application.html.erb file. How else do I insert it?
It's not "forbidden" outright - it just skirts a lot of important Rails conventions which will likely create problems & inconsistencies down the line
There are several elements to what you're asking. Here they are:
Layout
Firstly, you need to use the correct helpers in your layout:
#app/views/layout/application.html.erb
<%= stylesheet_link_tag "bootstrap/bootsrap" %>
The reason for this is the same as using helpers in other parts of your Rails application - as paths change between environments & certain "backend" functionalities of the system evolve, you can't rely on using vanilla HTML to call "Rails-centric" methods
A pro tip is that if there is any reference to a path, or an asset, you need to use the helpers which Rails provides
Asset Pipeline
Further to this, you need to appreciate how the "asset pipeline" works.
One of the big benefits of the Rails framework is that it gives you the ability to organize your assets in the most effective way - by keeping them in the /assets folder.
Whilst great for development, your problem will arise when you go into a production environment - Rails prefers to serve static assets in production, which means that the assets will be pre-compiled & access in the public folder:
In the production environment Sprockets uses the fingerprinting scheme
outlined above. By default Rails assumes assets have been precompiled
and will be served as static assets by your web server.
To make sure this works properly, you need to use the path helpers to load the files dynamically; hence allowing Rails to access the files wherever they are on the system
--
Manifest
I would strongly recommend you look into the "manifest" feature of the asset pipeline:
#app/assets/stylesheets/application.css
/*
*= require bootstrap/bootstrap
*/

Rails 4 Asset Pipeline: Asset missing fingerprint in asset_path from js

I am deploying a Rails 4.0 application which includes HTML partial templates as assets for our front-end javascript framework. Although these templates are part of the asset pipeline and are properly precompiled, when I call asset_path from embedded ruby in our js files, it returns the path to our templates without the fingerprint.
I am quite certain that this is purely a Asset Pipeline question, but to give you a complete sense of our tech stack: We use Rails 4.0, Ruby 2.1, AngularJS for our front-end MVC framework, and AssetSync to synchronize our assets between Rails and our CDN.
An example of where this occurs (in a file included in app/assets/application.js.erb:
$routeProvider
.when('/', {
templateUrl: "<%= asset_path 'home.html' %>",
controller: "HomeController"
});
This works great locally, but as soon as config.assets.digest = true in production, the call to asset_path does not properly factor in the fingerprint. The templates are in the app/assets directory within a new subdirectory templates. So in the above example, the home.html asset is at app/assets/templates/home.html. Our javascript has itself been precompiled at that point, so I'm thinking that it might be an issue of which order the assets are precompiled in.
I've noticed a few issues on the Rails Github (1, 2, 3) and a couple of SO posts about fingerprints not being set properly (1, 2), but can't find anything about them not being included at all...
Any help or ideas that you can provide would be much appreciated.
Edit 4/15: forgot to include that the extensions on my application javascript file DOES include .erb (app/assets/application.js.erb). Thanks Alex for catching that. I've updated it above.
Also, following instructions in this article on Heroku, I confirmed that running puts helper.asset_path("home.html") from within a Rails console running in production prints a properly fingerprinted URL for that asset.
This appears to be an issue with the AssetSync gem. I removed it, reconfigured the app so that Rails serves the assets, and the fingerprinting works fine.
If anyone else finds this question and is running into the same issue, I would recommend against using AssetSync. According to Heroku:
Many developers make use of Amazon’s S3 service for serving static assets that
have been uploaded previously, either manually or by some form of build process.
Whilst this works, this is not recommended as S3 was designed as a file storage
service and not for optimal delivery of files under load. Therefore, serving
static assets from S3 is not recommended.
Amazon CloudFront is the preferred method of serving assets through a CDN, and is very easy to configure with a Rails app that serves its own static assets, accomplishing the same goals as AssetSync.
I'm pretty new to this stuff, but to get the asset_path to work, don't you need a .erb on the end of that file?
Check out the bottom of this article for more info:
https://devcenter.heroku.com/articles/rails-4-asset-pipeline
If it works in development, that may not help. There is a helpful section on debugging at the bottom of the article though.
Update
Here's another article that could help:
https://medium.com/self-directed-learning/9ba1f595102a
Flipping on this configuration in Heroku made some of my asset pipeline problems go away:
heroku labs:enable user-env-compile -a yourapp
Hope this helps!
Alex

User custom theme support with rails assets pipeline

I have a rails app that allows users to create their own website easily but they share the same page structure.
I plan to switch my classic rails views for a templating language such as liquid or handlebars.
The goal is that my users could upload their own version of templates and css to completely customize the look and feel of their website.
Example of workflow :
User upload a theme folder containing Templates and Css files
Their website automatically uses this new templates and designs
Is it possible to do that and continue to take advantages of the Rails Assets pipeline?
Thanks a lot for your answers !
This might be something you can try: http://www.krautcomputing.com/blog/2012/03/27/how-to-compile-custom-sass-stylesheets-dynamically-during-runtime/.
I've used this in a Rails 3.2x project and it works fine, but I'm having difficulties getting it working in a different (somewhat modified Rails 4 project).
It's older article about compiling css on the fly using the Sprockets::StaticCompiler class.

How to use Bootstrap from Twitter in a Rails 3.0 application?

In my rails 3.0.10 I would like to use Bootstrap from Twitter but I only found examples using Rails 3.1 and the Asset Pipeline. How would add it to my 3.0 application? Do I just download it from the main site and put the files inside of my public folder? What about using LESS?
The absolute simplest way is to drop the boostrap.css file into your public folder and then reference it in your layouts/application.html.erb file. Then you can start using it right away. You're a bit limited at that point in what you can modify but that will get you started.
What is your question about LESS? bootstrap uses LESS but you don't have to worry about that since you're just using a plain ole css file.
See this railscasts video: Twitter Bootstrap Basics. There is another follow-up screencast after you finish this one.
We converted bootstrap to use SASS (think I found it in a github repo somewhere), and included it in the lib/assets/ folder.
Our application.css includes the partials. We've made a few custom modifications to the partials, works just fine.
Version 2 will be converted to SASS pretty sure I'm sure, but in the meantime there are asset pipeline modules available for LESS which you could add so that your rails app understands less files:
A quick search found this (can't vouch for it at all)
https://github.com/metaskills/less-rails
If it works as described you could just drop in bootstrap as it is and reference it in your application.css file.

Resources