Rails assets pipeline issue - ruby-on-rails

I have this piece of code in my css file
<%= asset_path 'dataTables/images/back_enabled.png' %>
But it doesn't get executed. It still remains raw code in browser. What am I missing?
I am in development environment.

You may use this only in files with erb extension, so you should give a name to your file like file.css.erb or something.
Ruby on Rails Guides: Asset Pipeline
2.2.1 CSS and ERB The asset pipeline automatically evaluates ERB. This means that if you add an erb extension to a CSS asset (for example,
application.css.erb), then helpers like asset_path are available in
your CSS rules:
.class { background-image: url(<%= asset_path 'image.png' %>) }

Related

How to inline CSS in Rails Header with Webpacker assets

I would like to inline some CSS within my html. I have done this in the past with Sprockets putting something like that in my layouts/application.html.erb
<style>
<%= Rails.application.assets["application.css"].to_s.html_safe %>
</style>
Now I would like to do the same but with CSS assets bundled by Webpacker.
I am able to get the path of the file with Webpacker.manifest.lookup("application.css"), but I am missing the latest part to get the content and embed it into the layout
The rationale behind this:
To improve page speed I want to embed my critical CSS into the header of the HTML. Using Webpack and PostCss tools (PurgeCss). I am able to get a very compact very of my CSS for the above the fold of my home page.
The rest of the CSS is loading asynchronously with the usual packs helpers
Update 1
Here is the link to the article I wrote thanks to the answer.
https://dev.to/adrienpoly/critical-css-with-rails-and-webpacker-sprocketsless-part-1-2bck
Let's consider having a line in app/javascript/packs/application.js
import `../css/application.css'
and a file app/javascript/css/application.css with some useful content.
Then you spell
<style>
<%= File.read(File.join(Rails.root, 'public', Webpacker.manifest.lookup('application.css'))).html_safe %>
</style>
and it simply works.
Don't forget:
To set extract_css: true in config/webpacker.yml
Exec rake webpacker:compile after changing these .css and/or .js files. Or use webpack-dev-server for a things like Hot Module Replacement
Turn on (though this is default setting for development) config.public_file_server.enabled = true (as #Adrien mentioned in comments) for serving .js resources by puma

Themeforest to Rails App

This is my first time using an external HTML theme for a rails app. I have downloaded a theme from Themeforest. Of course it comes with tons of JS, CSS and images. I was wondering what workflow most of you guys use when integrating a theme into your rails app.
Do you put all the downloaded assets in the public folder? Or do you put them in appropriate folders in app/assets and then fix the image urls etc.?
I think this question will get answers based on opinion, but you can try this gem to install static html for your application (not tested) . install_theme gem. For reference to use this gem read this blog
http://drnicwilliams.com/category/ruby/ruby-on-rails/page/2/ (If I put tuts in here my answer will full post)
For your question :
Do you put all the downloaded assets in the public folder? Or do you put them in appropriate folders in app/assets and then fix the image urls etc.?
My workflow looks like :
Put css, js, image, font files to assests directory
-assets
- fonts
- images
- javascripts
- stylesheets
Editing url image, url font in css files and js files.
If I use extention css.erb for css file, url image, url font should edit looks like :
image :
background-image:url(<%= asset_path 'bg.png' %>);
font :
#font-face {
font-family: namefonts;
src: url('<%= asset_path('namefonts.eot') %>');
src: url('<%= asset_path('namefontsd41d.eot') %>?#iefix') format('embedded-opentype'),
url('<%= asset_path('namefonts.woff') %>') format('woff'),
url('<%= asset_path('namefonts.ttf') %>') format('truetype'),
url('<%= asset_path('namefonts.svg') %>#icons') format('svg');
font-weight: 400;
font-style: normal;
}
If I use extention css.scss
image :
background : image-url("bg.png")
font :
#font-face {
font-family:'namefonts';
src:font-url('namefonts.eot');
src:font-url('namefonts.eot?#iefix') format('embedded-opentype'),
...
}
Choose html structure to layout template (head tag, header, navbar, sidebar footer), partial template (contents, forms etc) - If I use html.erb
-views
- layouts
- partials
- form
- index
Coding Links to Assets
<%= stylesheet_link_tag "application", media: "all" %>
<%= javascript_include_tag "application" %>
Editing image tag, url tag, form tag etc to conform with rails template (erb file)
image tag
example in html
<img src="images/rails.png" class="theclass"/>
change to
<%= image_tag "rails.png", :class => 'theclass' %>
link tag
example in html
Home
change to
<%= link_to "Home", root_path %>
form tag you can read this
<%= form_tag("action", method: "post") do %>
<%= label_tag(:q, "Label for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Save") %>
<% end %>
Editing any file to conform with rails
You can read this
Assets Pipeline
Layouts and Rendering in Rails
Form Helpers
Updating the asset pipeline
The fix is pretty simple. Open your project's config file, located at config/application.rb and add the following line within your Application class:
config.assets.paths << Rails.root.join("app", "assets", "fonts")
config.assets.precompile += %w( .svg .eot .woff .ttf )
Do you put all the downloaded assets in the public folder? Or do you
put them in appropriate folders in app/assets and then fix the image
urls etc.?
The bottom line is if you're going to do the job, do it right
To do this, I would personally integrate the theme from the ground-up. Firstly, by changing the various layouts you may have (to accommodate the classes & styling of the theme), and then working through each part of the system to style it accordingly.
--
Assets
In order to render the assets correctly, I would most certainly include them in the app/assets folder, rather than public/____. Reason being they are part of the general assets of the application, and need to be kept within the asset pipeline.
I would therefore basically do 3 things:
Put the images from the theme into app/assets/images
Put the stylesheets from the theme into app/assets/stylesheets
Put the javascripts from the theme into app/assets/javascripts
I would then go through the application & work to get the styling to work correctly (starting with the layout as mentioned).
I think it's important to point out that in order to achieve the best results, you will be best doing things right -- sitting down and working through the styling properly.
here's my workflow:
I usually structure my assets like this (say it's an admin template and theme files are in sass)
/app
/assets
/stylesheets
/admin
_modal.scss
_reset.scss
_button.scss
....
/vendor
/bootstrap
bootstrap.min.css
/font-awesome
....
admin.scss.scss
inside admin.css.scss
#import 'vendor/bootstrap/bootstrap';
#import 'admin/modal';
#import 'admin/reset';
#import 'admin/button';
I usually do the same with javascript
as for the html's
I usually do render per section (one partial for the topbar, sidebar etc..)
I usually place them in
/app
/views
/partials
so I'm calling
<%=render '/partials/topbar'%>
Hope this helps

Rails: How to reference images in CSS within Rails 4

There's a strange issue with Rails 4 on Heroku. When images are compiled they have hashes added to them, yet the reference to those files from within CSS don't have the proper name adjusted. Here's what I mean. I have a file called logo.png. Yet when it shows up on heroku it is viewed as:
/assets/logo-200a00a193ed5e297bb09ddd96afb953.png
However the CSS still states:
background-image:url("./logo.png");
The result: the image doesn't display. Anybody run into this? How can this be resolved?
Sprockets together with Sass has some nifty helpers you can use to get the job done. Sprockets will only process these helpers if your stylesheet file extensions are either .css.scss or .css.sass.
Image specific helper:
background-image: image-url("logo.png")
Agnostic helper:
background-image: asset-url("logo.png", image)
background-image: asset-url($asset, $asset-type)
Or if you want to embed the image data in the css file:
background-image: asset-data-url("logo.png")
Don't know why, but only thing that worked for me was using asset_path instead of image_path, even though my images are under the assets/images/ directory:
Example:
app/assets/images/mypic.png
In Ruby:
asset_path('mypic.png')
In .scss:
url(asset-path('mypic.png'))
UPDATE:
Figured it out- turns out these asset helpers come from the sass-rails gem (which I had installed in my project).
In Rails 4, you can reference an image located in assets/images/ in your .SCSS files easily like this:
.some-div {
background-image: url(image-path('pretty-background-image.jpg'));
}
When you launch the application in development mode (localhost:3000), you should see something like:
background-image: url("/assets/pretty-background-image.jpg");
In production mode, your assets will have the cache helper numbers:
background-image: url("/assets/pretty-background-image-8b313354987c309e3cd76eabdb376c1e.jpg");
The hash is because the asset pipeline and server Optimize caching
http://guides.rubyonrails.org/asset_pipeline.html
Try something like this:
background-image: url(image_path('check.png'));
Goodluck
In css
background: url("/assets/banner.jpg");
although the original path is /assets/images/banner.jpg, by convention you have to add just /assets/ in the url method
None of the answers says about the way, when I'll have .css.erb extension, how to reference images. For me worked both in production and development as well :
2.3.1 CSS and ERB
The asset pipeline automatically evaluates ERB. This means if you add an erb extension to a CSS asset (for example, application.css.erb), then helpers like asset_path are available in your CSS rules:
.class { background-image: url(<%= asset_path 'image.png' %>) }
This writes the path to the particular asset being referenced. In this example, it would make sense to have an image in one of the asset load paths, such as app/assets/images/image.png, which would be referenced here. If this image is already available in public/assets as a fingerprinted file, then that path is referenced.
If you want to use a data URI - a method of embedding the image data directly into the CSS file - you can use the asset_data_uri helper.
.logo { background: url(<%= asset_data_uri 'logo.png' %>) }
This inserts a correctly-formatted data URI into the CSS source.
Note that the closing tag cannot be of the style -%>.
Only this snippet does not work for me:
background-image: url(image_path('transparent_2x2.png'));
But rename stylename.scss to stylename.css.scss helps me.
WHAT I HAVE FOUND AFTER HOURS OF MUCKING WITH THIS:
WORKS :
background-image: url(image_path('transparent_2x2.png'));
// how to add attributes like repeat, center, fixed?
The above outputs something like: "/assets/transparent_2x2-ec47061dbe4fb88d51ae1e7f41a146db.png"
Notice the leading "/", and it's within quotes.
Also note the scss extension and image_path helper in yourstylesheet.css.scss. The image is in the app/assets/images directory.
Doesn't work:
background: url(image_path('transparent_2x2.png') repeat center center fixed;
doesn't work, invalid property:
background:url(/assets/pretty_photo/default/sprite.png) 2px 1px repeat center fixed;
My last resort was going to be to put these in my public s3 bucket and load from there, but finally got something going.
Referencing the Rails documents we see that there are a few ways to link to images from css. Just go to section 2.3.2.
First, make sure your css file has the .scss extension if it's a sass file.
Next, you can use the ruby method, which is really ugly:
#logo { background: url(<%= asset_data_uri 'logo.png' %>) }
Or you can use the specific form that is nicer:
image-url("rails.png") returns url(/assets/rails.png)
image-path("rails.png") returns "/assets/rails.png"
Lastly, you can use the general form:
asset-url("rails.png") returns url(/assets/rails.png)
asset-path("rails.png") returns "/assets/rails.png"
Interestingly, if I use 'background-image', it does not work:
background-image: url('picture.png');
But just 'background', it does:
background: url('picture.png');
In some cases the following can also be applier
logo { background: url(<%= asset_data_uri 'logo.png' %>) }
Source: http://guides.rubyonrails.org/asset_pipeline.html
You can add to your css .erb extension. Ej: style.css.erb
Then you can put:
background: url(<%= asset_path 'logo.png' %>) no-repeat;
When using gem 'sass-rails', in Rails 5, bootstrap 4, the following worked for me,
in .scss file:
background-image: url(asset_path("black_left_arrow.svg"));
in view file(e.g. .html.slim):
style=("background-image: url(#{ show_image_path("event_background.png") })");
This should get you there every single time.
background-image: url(<%= asset_data_uri 'transparent_2x2.png'%>);
By default Rails 4 will not serve your assets. To enable this functionality you need to go into config/application.rb and add this line:
config.serve_static_assets = true
https://devcenter.heroku.com/articles/rails-4-asset-pipeline#serve-assets
In Rails 4, simply use .hero {
background-image: url("picture.jpg");
} in your style.css file as long as the background image is tucked in app/assets/images.
This worked for me:
background: #4C2516 url('imagename.png') repeat-y 0 0;

CSS in Rails Asset Path not processed by ERB in development

I have a Rails app with the following in /app/assets/stylesheets/styles.css.erb:
...
#nestedbg {
background-position: left top;
background-image: url(<%= asset_path 'siteheader2.png' %>);
background-repeat: repeat-x;
background-attachment: fixed;
}
...
When I run rake assets:precompile and then run rails s -e production, everything works as expected. However, when I remove the precompiled assets and run rails s in development, the CSS file comes up as shown above instead of being properly substituted.
I tried putting config.assets.compile = true in /config/environments/development.rb and that did not help.
Any ideas?
Thanks.
I honestly cannot say why this is not interpreted correctly in your case, but I have a much better workaround to offer: skip erb interpreting altogether.
You can do this like so:
/* styles.css.scss */
background-image:url(image_path("siteheader2.png"));
If you did not have a chance to I would also suggest to have a look at SASS: it is integrated in the Rails asset pipeline and lets you do cool things like variable declarations, nesting, mixins, ...
I found that my css files wouldn't be processed by ERB unless SCSS processing was also added.
I changed my screen.css.erb to screen.css.scss.erb and now <%= asset_path 'file.png' %> is rendered correctly as /assets/file.png.
I'm on Rails 3.1.3.
I was using Rails 3.1.1 and when I switched the app to use Rails 3.1.3, the problem went away. I switched back to 3.1.1 to see if the issue came back and it did not.
I'm guessing that it was a problem with one of the gems and the update to 3.1.3 brought other gem updates with it.
Bizarrely, I found that changing asset_path to asset_data_uri and then back to asset_path worked for me. Was using Rails 3.1.3 all along.
Strange.
Sam Oliver's advice did the trick for me, simply renaming the extensions didn't update the timestamp on the files.
CSS and ERB
The asset pipeline automatically evaluates ERB. This means that if you add an erb extension to a CSS asset (for example, application.css.erb), then helpers like asset_path are available in your CSS rules:
.class { background-image: url(<%= asset_path 'image.png' %>) }
This writes the path to the particular asset being referenced. In this example, it would make sense to have an image in one of the asset load paths, such as app/assets/images/image.png, which would be referenced here. If this image is already available in public/assets as a fingerprinted file, then that path is referenced.
If you want to use a data URI — a method of embedding the image data directly into the CSS file — you can use the asset_data_uri helper.
CSS and Sass:
When using the asset pipeline, paths to assets must be re-written and sass-rails provides -url and -path helpers (hyphenated in Sass, underscored in Ruby) for the following asset classes: image, font, video, audio, JavaScript and stylesheet.
image-url("rails.png") becomes url(/assets/rails.png)
image-path("rails.png") becomes "/assets/rails.png".
The more generic form can also be used but the asset path and class must both be specified:
asset-url("rails.png", image) becomes url(/assets/rails.png)
asset-path("rails.png", image) becomes "/assets/rails.png"
Referenced By: Rails Guide Asset Pipe Line
Heading: 2.2.1 and 2.2.2 respectively.

Asset Subdirectories in Rails 3.1

I have a Rails 3.1 app with an image:
app/assets/images/icons/button.png
It seems like the image should be served at this URL:
assets/icons/button.png
but if I go to this URL I get a 404. To fix this I created an initializer and added my images/icons subdirectory to the asset path:
Rails.application.assets.append_path "app/assets/images/icons"
However, this does not seem like it can possibly be the recommended way to accomplish this. I'm aware of the require and require_tree directives for JavaScript and CSS assets, is there an equivalent for image assets? How are other people doing this?
EDIT: As of Rails 3.2.rc1 this is now fixed! asset_path now generates proper paths when deploying to sub-uri!
For images it just works. Rails packages everything in images/ tree. I personally use them like this (actual code):
CSS:
a#icon-followers{
background: url(<%= asset_data_uri "icons/followers.png" %>) center center no-repeat;
}
(asset_data_uri actually makes the images inline in the CSS file using base64, but that's irrelevant in this case)
No custom configuration required. After precompiling, images from app/assets/icons/ end up in public/assets/icons/.
You can open public/assets/manifest.yml to see how Rails translates the paths to actual files.

Resources