Rails - Make two different footers to appear on certain pages - html

I'm looking to have two different footers, and have one appear on specific pages. The site has a lot of pages, so I don't want to just hardcode each footer into each page.
In rails, how can I put in logic to have which footer appears on which page? Is there an 'if' statement I can put directly on the _footer partial that displays the footer by page?
Thanks in advance for your help!

Your going to want to have two different layouts. If you show me some of your code i will be about to help you out a little more.

You can crate two different layouts( add .erb file to direcroty layouts in views ) or can create two partial and use them when you want, for example:
In your Controller add
class Controller
...
# You may use class or instrance variable
def your_method
# your logic...
#footer_variable = true
end
in your layout file add
<%= if #footer_variable %>
<%= render 'optional_footer' %>
<%= else %>
<%= render 'footer' %>
<%= end %>
and add to your layout's directory file footer.html.erb with your normal footer and optional_footer.html.erb
Optional Footer
<div>
<span>I'm your optional footer</span>
</div>
Normal Footer
<div>
<span>I'm your normal footer</span>
</div>``
If instance variable will be availiable in layout it will ber rendered optional footer otherwise normal footer( from your layout )

Related

change body background depending on the page rails

I'm using bootstrap-sass in my rails app which works fine however one particular page 'welcome' I want the body to have have different color.
If I open the welcome.scss file in the assets and add
html, body {background:#000000;}
I get no change and the bootstrap white overrides the change I expect to happen.
How do I get it to change for that page.
It was my understanding that the page css only loads in when you are on that page - am I wrong and would it just be the same as writing in the Application.scss file?
It was my understanding that the page css only loads in when you are on that page
The CSS which loads is dependent entirely upon the stylesheet_link_tag in your layout:
#app/views/layouts/application.html.erb
<%= stylesheet_link_tag :application %>
The way in which you load this determines the stylesheets which load each page.
--
For example, the standard Rails way to load your stylesheets is to use the "sprockets" files & directives to append the required files into your application.css sheet. Although this works in any other sheet, it's mainly used with application.
Since you're using bootstrap (which tells you the following):
#app/assets/stylesheets/application.css
/*
*= require bootstrap_and_overrides
*/
... you'll need to make sure you know which files you want to load. Specifically, your assertion that page-specific CSS being loaded is false; you either hard-code the loads, or put the code into a single file (EG application):
#app/views/layouts/application.html.erb
<%= stylesheet_link_tag :application, controller_name #=> loads controller CSS page each time you load a new controller %>
--
For you, I would do the following:
#app/views/layouts/application.html.erb
<body class="welcome if action_name == 'welcome'">
Then you'd be able to use the following:
#app/assets/stylesheets/application.css
body.welcome {background:#000000;}
If you wanna customize the style for a specific controller or action you can follow this:
Add controller name/ action name (if needed) to layout file, application.html.erb is in my example:
<!DOCTYPE html>
<html>
<head>
<!-- My header template -->
</head>
<body class="<%= controller_name %>_body action_<%= action_name %>">
<!-- My body template -->
</body>
</html>
Add css in a suitable file. Eg: controler_name = 'home', action = 'index'. So my css will be (Notice that I don't use action = 'index' here to css, it may be needed in your case)
body {
background: NORMAL_COLOR;
&.home-body {
background: SPECIAL_COLOR;
}
}
If you are loading that css file only in that particular page, then it will be applicable only to that page. Otherwise it will apply to all of the pages.
So in nutshell, it is same as writing in Application.scss.
css classes applied in same order as you defined in declaring them. So to apply welcome.scss you need to declare it after bootstrap css file.
Further you can make use of !important
This is how you can define page specific css files in <head> section:
In your application.html.erb you can define
<% if content_for?(:head) %>
<%= yield(:head) %>
<% else %>
# default css file
<% end %>
And in your pages (welcome page for this particular instance), you can define your respective css file like this:
<% content_for :head do %>
<link rel="stylesheet" href="/assets/welcome.scss">
<% end %>
Hope it helps!

Adding HTML tags (e.g. break tag) to embedded Ruby block

Note: I am a Ruby on Rails newbie so excuse this question if it seems too obvious. But for the life of me, I can't figure out where to add an HTML break tag to this Ruby code to make the elements stack on top of each other, not beside each other.
<p>
<strong>Genres:</strong>
<%= #book.authors.map {|a| a.name}.join(', ') %>
</p>
I have added the break tag after the %> and before it, inside the join method area with the comma, and everywhere else you can imagine and nothing works, it just places the data results beside each other sequentially. I am sure it's something simply but I can't figure it out.
Any help on this would be appreciated.
The typical Rails way to do this is with a for or each loop:
<p>
<strong>Authors:</strong>
<% for author in #book.authors %>
<%= author.name %><br/>
<% end %>
</p>
The for statement could also be #book.authors.each do |author|. From an HTML and CSS perspective, I would argue that it is much better to put each author in their own container element such as <li>, which can be styled to look the way you want.

Writing a Ruby method in the model that outputs HTML in the view

I've got a method in my view that decides which HTML to print out depending on the class of the object it gets:
<% def laybricks(c,stream) %>
<% if c.is_a?(Post) %>
<article>
// Tons more HTML unique to posts
</article>
<% elsif c.is_a?(Photograph) %>
<article>
// Tons more HTML unique to photographs
</article>
<% end %>
<% end>
But I now know more about Rails since writing it. How can I transfer this to my model so that I can call the method in the view and have it print the HTML the same?
Method in a view would definitely be better moved to the helper.
But for your need the best solution is partials utilizing some rails magic:
<%= render #c %>
will magically render partial _post.html.erb if #c is an instance of Post and _photograph.html.erb if it is instance of Photograph. These partials should be in the same view folder, and you can reference your object as post and photograph in each partial respectively.
For more info see Rails Rendering Guide.
ADDON:
How can I transfer this to my model so that I can call the method in the view and have it print the HTML
It is usually not a responsibility of a model to generate HTML, but if you ultimately want to do this, the best way is to use a design pattern that is usually referred to as Presenter or Decorator. E.g. draper gem exists for this, but also many other. And there is many discussions in Rails community how this pattern should be called, how it should be implemented and is it worth it at all.
UPDATE:
Application Helper
def laybricks(c,stream)
content = []
if c.is_a?(Post)
content << "<article> </article>"
elsif c.is_a?(Photograph)
content << "<article> </article>"
end
end
Your View
<%= raw laybricks %>
OR
<%= laybricks.html_safe %>
NOTE: The raw helper will allow the plain html to get interpreted. You can also use html_safe method to interpret the same.

ruby on rails datatype :text render in view

I try to use scaffolding in rails to build a blog. I save my blog's content as :text.
However, when I see the view. It can only show in one line. It looks not good.
How can I solve this problem?
Your database stores text, not HTML. In HTML line breaks are ignored unless they are marked up with relevant HTML tags. For example, a break between two paragraphs should be marked by the end of one <p> element and the beginning of another, and a single line break should be represented by a <br> tag.
Rails' simple_format helper converts text to HTML by replacing line breaks with HTML tags.
So instead of something like this:
<p><%= #post.content %></p>
You would do this:
<%= simple_format #post.content %>

Rails content_tag helper for simple things?

Should I be using the content_tag helper for all html tags when working with Rails?
Is it The Rails Way to use content_tag for even simple things like Header tags?
<%= content_tag :h2, :class => "bla bla" do %>
Header
<% end %>
vs.
<h2>Header</h2>
Clearly just using straight html is much 'simpler' and 'shorter', but what is the correct Rails Way of doing things?
Using content_tag when you don't have to is a waste. There's no need to use ERBisms to generate static HTML so don't do it. If some other piece of code determines what tag to use, then you'd use content_tag to construct that tag.
If you are asking the rails way of doing this, then its defiantly using 'content_tag', but using tag_helpers has its own advantages and disadvantages
Personally for me I can see these things, (Using rails helpers instead of pure HTML)
Advantages
1 - Your code will be cleaner. (with less lines)
2 - You will have more control other the elements.
Ex: You can have your own helper tags like 'big_text_box' which will return a text box more than the normal with and you can use it across all the site
3 - You will be able to add attributes like class, id dynamically in the runtime
Disadvantages
1 - If you have a separate designer (I mean UI engineer) he/she will get confuse of by the code you have use. As its not pure html
2 - Its slow than the pure html (But this will not even noticeable unless otherwise your app is a damn major one...)
So its up to you to decide what to use, personally I prefer using rails helper tags as it makes me more comfortable
HTH
cheers
sameera
One useful method is the "div_for", which is somewhat similar to the content_tag. If you find yourself marking up HTML elements with data you can reference later, "div_for" makes your life much easier.
Let's say you have a bunch of people being shown on a page and you need to wrap each with a div that has a unique ID so you can modify these elements with JS. By hand and straight HTML you would have to do:
<% #people.each do |p| %>
<div id="person_<%= p.id %>"><%= p.name %></div>
<% end %>
That would get bothersome if you were doing LOTS of this with multiple attributes (I commonly use custom IDs, classes, and some data attributes). But using div_for you could write the above as:
<% #people.each do |p| %>
<%= div_for(p) do %><%= #person.name %><% end %>
<% end %>
Makes the HTML a little easier to read when things get long and complex. I found it is much cleaner when working with javascript a lot.
http://apidock.com/rails/ActionView/Helpers/RecordTagHelper/div_for