Rails 4 Different background image for home and items index view - ruby-on-rails

I should like to set two different background images for the home page of my app and the index view for the items.
I tried this directly in the home view:
<div class="container" style="background: url('/assets/images/hom.jpg')">
but it doesn't display any image. Someone can help me please?
I already have tried to follow this post but it still doesn't work.
How to set a different background image for each page in Rails 3 site?

Try it without /assets/ in the URL. The rails assets pipeline does not require you to state that it is in an /assets/ directory

You could achive this by setting the appropiate CSS class and setting the image background in you stylesheets. Something like:
<div class="container home">
And in a SCSS file:
.container.home{
background-image: image-url("hom.jpg");
}
Keep in mind that image-url is a helper that should be used in .scss files.

I tried this in my pages:
<div style="background-image: url('/assets/hom.jpg')">
And it seems to work locally, but after a push on Heroku the images aren't displayed online.
In addition, the image appears cut, because is referred to a DIV, and I want it referred to the body of my pages.

One way to do this is by adding the controller and action names to the body tag in your layout. Then you can rely on pure CSS to serve different images. In your layout file you can do this:
<%= content_tag :body, class: "#{controller_name}-#{action_name}" do %>
<!-- Your layout content, or everything that should be in the body tag goes here -->
<% end %>
This would give you the following HTML:
<body class="items-index> <!-- or whatever the current controller/action are -->
Then, you can add the relevant CSS.
.items-index {
background-image: image-url("items_index.jpg");
}
.pages-home {
background-image: image-url("pages_home.jpg");
}
You can wrap this in a helper to make it cleaner.
def class_for_body
"#{controller_name}-#{action_name}"
end
Or even:
def body_tag(&block)
content_tag :body, yield, class: "#{controller_name}-#{action_name}"
end
See controller_name and action_name methods provided by Rails.

Related

Set up a bootstrap container for every view except one in Rails

I'm building a Rails app and I would like to use a bootstrap container for every view except one, the homepage. Ideally I would put the yield on application.html.erb inside the container so that it will include every view, but this would also be including the homepage. Is there an easy way to exclude only the homepage?
application.html.erb
<body>
<div class="container">
<%= yield %>
</div>
</body>
You can create an additional layout in your app/views/layouts/ directory. Then use that layout for that action you need.
class YourController < ApplicationController
layout "your_new_layout", only: :your_action
...
end
Refer to the documentation on Ruby on Rails Guide for additional information.
You can either create a separate layout as mentioned above or you just add an if statement into the view which excludes the controller and action like so:
<% unless params[:controller] == "pages" && params[:action] == "home" %>
<div class="container">
<% end %>
You always have access to the controller and action through the params.
Don't forget to also do that for the ending div.
I prefer this if it is just a small change to the acutal layout - but different layout makes more sense if there are a lot of changes.

Rails: How to put stuff in header

In my Rails App I included OneSignal which requires the following link to be placed in the head of the document:
<link href='/manifest.json' rel='manifest'>
Unfortunately with Rails I cannot put this link there, because the entire layout gets rendered inside the body.
While this ...
$(document).ready(function(){
$("head").append("<link href='/manifest.json' rel='manifest'>");
});
seems to work in development mode, it does not work in production.
How can I add this link to my head section of the document?
If you don't want to make a site wide change (adding the script to every page on the site) you can pick the page you want to put it on and add to the .htmlerb file
<%= content_for :header %>
<%= javascript_include_tag "script.js" %>
<%= end %>
javascript_include_tag will allow you to send content from the controller to the header and if script.js is in your app/assets/javascript directory, that will be added to the header.
Another option is to make a specific layout and have the pages that need the script use that layout, by calling it in the controller like so:
def users_index
#user= User.find(params[:id])
layout: users_index layout
end
That will load the users_index_layout.html.erb file from app/views/layouts...if it exists, and complain loudly if it does not.
You can add <link href='/manifest.json' rel='manifest'> in app/views/layouts/application.html.erb.

Why do image tags work in regular views but not mailer views?

Why does the below code show images on regular Rails views (webpages) but not show the images when used in mailer views (i.e. the emails I send from the app)? The images are located in /app/assets/images.
<%= image_tag "hr1.png" %>
<%= image_tag "pic_mountain.jpg" %>
<%= link_to image_tag("hr1.png", alt: "Sample alt text"), 'http://google.com' %>
As a follow up, is this the best way to include images in html emails being sent to users? Should I somehow store the images at www.url.com/images/sample_pic.jpg? If so, how do you do this? I'm using mailer classes I created that inherit from ActionMailer. Also, this is Rails 4.1.6. Thanks!
The ERB you posted generates html of the form
<img src="/assets/hr1.png" />
(Iglorying asset digests for brevity), ie it contains only the path to the image and the browser uses the host and protocol the containing page was loaded from.
In an email this doesn't work because there is no such host. You can either include the host in the url or add the images as inline attachments.
The most basic way for the first is to do something along the lines of
image_tag(image_url("foo", host: "example.com"))
You can also set default_url_options on your mailer so that you don't have to do this over and over again.
For inline attachments you first add the image as an attachment (in your mailer)
attachments.inline['foo.png'] = File.read(Rails.root.join("app", "assets", "images", "foo.png")
And then in your view you use it like so:
<%= image_tag attachments['foo.png'].url -%>
Note that this turns your email into a multipart email, so you shouldn't try and force the content type to text/html

Rails image broken link

I'm trying to link to an image in rails and its not working. I can link to assets/file.css as well as assets/file.js but assets/file.jpg doesnt work.
I tried a fresh rails new project_name and when i open the homepage and the rails logo doesnt show.
As a side question,
How do I get rails to load only the application.js and application.css
I see that if i remove ?body=1 from the URL it compresses them all into one file, but when I view the page using the following code it leaves those files blank and includes them one by one as separate scripts.
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
Ok so that's an expected behavior, you have to use Rails helpers:
<%= image_tag "file.jpg" %>
Your css files should be .erb. Within it, use:
.class { background-image: url(<%= asset_path 'image.png' %>) }
Reference is para 2.2.1 here.
I just checked my code and my CSS looks like this:
background-image:url(/assets/pinstripes.jpg);
with the image uploaded to app/assets/images, of course. This looks like what you're using, but I can't tell for sure.

Best way to handle dynamic css in a rails app

I'm researching a problem for handling dynamic css in a rails app. Within the app, individual users and/or groups of users can have customized look and feel that is accomplished via CSS. There will not be any fixed number of "look and feels" or css files, the number will grow as the number of users and groups grows and the look and feel is defined by the users via the application's admin interface. Throughout the course of a typical day thousands (it not tens of thousands) of different variations of the css will be served up. The app will store the pre-built css in mongodb, so there it will not have to pay the price of constructing the css for every request, the question is more about how is the best way to serve up this dynamic css content. I've seen other questions like [this one][1] that speak to using erb or sass, but some of these answers are dated by several years so I wanted to make sure there wasn't a better answer with Rails 3.
You can treat your CSS files as resources, store them on the database, and serve them with page caching, so that you only need to hit the db once when the CSS is modified. All later requests will be served directly by the web server from the cache, without ever touching your app or db.
# stylesheet.rb
class Stylesheet < ActiveRecord::Base
validates_presence_of :contents
end
# stylesheets_controller.rb
class StylesheetsController < ApplicationController
caches_page :show # magic happens here
def show
#stylesheet = Stylesheet.find(params[:id])
respond_to do |format|
format.html # regular ERB template
format.css { render :text => #stylesheet.contents, :content_type => "text/css" }
end
end
# the rest is your typical RESTful controller,
# just remember to expire the cache when the stylesheet changes
end
# routes.rb
resources :stylesheets
# layouts/application.html.erb
…
<link href="<%= stylesheet_path(#current_user.stylesheet) %>" rel="stylesheet" type="text/css" />
Well, I have worked with this a couple of times but they were definitely fixed no of CSS files to choose from. Its should be the same more or less.
One of things I used alot was the content_for blocks. Basically
<% content_for :css do %>
// some css file or css content
<% end %>
And in the layout
<%= yield :css %>
very simple way for managing the layouts.
This might give you a few ideas: Multiple robots.txt for subdomains in rails
I had a similar problem - but needed to serve the modified CSS only once.
I store a couple of constants in a module 'Site' - which I can then use as constants in CSS or as constants throughout the Rails application. I auto-generate the CSS files whenever the Rails application restarts and the CSS input files were modified.
You could do something similar, but reference symbolic names in site_settings.rb
and then fetch those on a per-user basis from MongoDB
http://unixgods.org/~tilo/Ruby/Using_Variables_in_CSS_Files_with_Ruby_on_Rails.html
Now let's say you have some dynamic styling called dynamic.css.scss.erb (the .erb at the end is important!) in app/assets/stylesheets. It will be processed by erb (and then by Sass), and as such can contain stuff like
.some_container {
<% favorite_tags do |tag, color| %>
.tag.<%= tag %=> {
background-color: #<%= color %>;
}
<% end %>
}

Resources