Modular page layout - ruby-on-rails

I would like to display certain things on every or almost every page of my application. Things like header, footer, sidebar or navigation.
How would I go about doing that? I am coming from languages like PHP and ColdFusion where I would either include files or call a function to display what I want. I am having a hard time understanding how I can implement it in Rails.

Generally in your application layout, you use partials. A small example would look like
<body>
<%= render :partial => 'shared/header' %>
<%= yield %>
<%= render :partial => 'shared/footer' %>
</body>
Hope this helps.

Your application should have app/view/layouts/application.html.erb. That's where your html content goes.
In the application.html.erb, you should see <%= yield %>. This is where specific views for different controller actions with corresponding views go.
For your css files for application.html.erb, you should use app/assets/stylesheets/application.css.
For your javascript files for application.html.erb, you should use app/assets/javascripts/application.js.

Related

how to override the heading on rails new/edit form

using Rails 3, Ruby 1.9, with bootstrap and jQuery.
In my _form.html.erb I have:
<%= form_for(#system_cat, :html => {:class => "form form-horizontal system-cat"}) do |f| %>
application.html.erb has:
<html>
<head>
<title>System Catalog</title>
.
.
.
</head>
<body>
<%= yield %>
</body>
</html>
and the page ends up with:
.
.
.
<body>
<h1>New system_cat</h1>
.
.
.
Everything works fine, I would just like to replace the 'New system_cat' heading, same for the edit page which uses the same _form.html.erb file - it ends up with 'Edit system_cat'.
Try:
<h1><%= #system_cat.new_record? ? 'New' : 'Edit' %> system_cat</h1>
This is partially a followup to the comments discussion
As I wrote in the comments, the titles you refer to are actually (or at least, should be) in the specific action view files for new and edit (So new.html.erb and edit.html.erb). If you look at those files, they are actually calling your _form.html.erb partial. For example, this is what one of my new.html.erb looks like:
<h2>Add Device</h2>
<%= render :partial => 'form' %>
And the edit.html.erb looks like:
<h2>Edit Device</h2>
<%= render :partial => 'form' %>
Same thing; different title.
BroiSatse answer is good and will work, but my concern would be putting too much action-specific logic in your partials. As BroiSatse noted, sometimes its necessary to do something like that on occasion, but if you can avoid it, it usually makes for much cleaner code. So an alternative would be to simply edit the titles in those action view files instead.
As I wrote in the comments, the _form.html.erb doesn't (or shouldn't) care whether its being called from an edit or new action. Its the new and edit files, which call that partial, that should be responsible for setting general, action-specific, things like the title and such.

Application.html.erb template inheritance

I have a situation in rails (version 4.04, ruby version 2.1) where I've been using the standard application.html.erb to define the main framework for my site, header, footer, nav bar, etc. When I got to an inner div, call it, inner-content, thats where I put a <% yield %> statement so that the sub template can take over and place its content in the correct place (for example products#show or products#index have show.html.erb and index.html.erb respectively which just the content for those actions).
The problem is I realized I was duplicated some code in those sub templates. In ever one of them (except one) I always was starting off like this:
<div class="columns large-6 medium-6 center-small">
<div class="inner_wrapper">
And I was always ending like this:
</div>
</div>
So I was thinking, I shouldn't be repeating all this code. I should move this into application.html.erb so that every template automatically gets the inner-content set up correctly.
The problem is that one action I was talking about. There is one action that has a different setup. I don't want to have to type in those extra 2 divs for every sub-layout except one. Is there a better way to do this?
One way could be to check which controller your currently using this in your application.html.erb
<% if params[:controller] == "controller name" %>
<div>
<%= yield %>
</div>
<% else %>
<div class="different div">
<%= yield %>
</div>
<% end %>
Not sure if this the best way, but its one way to do it.
Create a different layout file and call it maybe products_layout.html.erb.
Then in the controller
class ProductsController < ApplicationController
layout: 'products_layout'
....
end
Or do it on a per action
def show
render 'show', layout: 'products_layout'
end
http://guides.rubyonrails.org/layouts_and_rendering.html

Rails 4: Nested Layouts?

I have a main layout (application) and two 'sub' layouts (dashboard and admin). In my dashboard and admin controllers respectively I have a before_filter which render templates: the template I want (either dashboard or admin).
In my dashboard and admin layouts, I am doing something along the lines of:
<% content_for :top_menu do %>
<%= render partial: "layouts/menu/top", locals: {section: 'admin'} %>
<%= render partial: "layouts/menu/sub", locals: {section: 'admin'} %>
<% end %>
So this is including the top partials with a section local which shows the correct options I want.
In my application layout, I have the following:
SOME HTML HERE
<%= yield :top_menu %>
SOME HTML HERE
<%= yield %>
SOME HTML HERE
The problem is that the content from my views isn't being displayed, I'd expect it to be displayed where the 'yield' is in my application layout.
I have read: http://guides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts - but following that just displays the menus twice and still doesn't display my content.
I think I am failing to understand something here, help would be appreciated.
In short, I want top menus and it's in the controller that I want to specify which menu is to be used. I'm sure there is a better solution to this that I am missing also.
I have fixed this by doing:
layout 'menu/admin'
In my controller, and adding:
<%= render template: "layouts/application" %>
To my layouts.

RoR: How do I validate my pages when sometimes I have CSS links not in the HEAD?

I get this error when using the w3 validator: document type does not allow element "link" here
I mean, I know style links are suppossed to be in the head, but for an RoR project, it's more.. efficient? to only load what you need? cause, lets say, A stylesheet is loaded in a partial. and that partial is used on multiple pages. It makes sense, as far as DRYing things up goes, to include the stylesheet with the partial.
But it seems like DRYing things goes against W3C.
What do I do?
You shouldn't be putting <link> elements into your content like that. You can use ERB's blocks to yield the content into another part of your layout template, like this:
<% content_for :head do %>
<%= stylesheet_link_tag 'my_partial_styles' %>
<% end %>
<p>Your partial content...</p>
In your application layout, you can yield this content where it belongs:
<head>
<%= yield :head %>
</head>

How to use an RoR application template and still be able to add things to the html head?

I'm learning RoR through this tutorial. In tute, an application.html.erb file is created in views/layouts. In the body, a content div is created, and the <%= yield %> line is used. The other views that are created are then just inserted into the content div in the body of the application template.
But there are a few views that I have where I need to add some javascript to the head.
My question is, how can I use this structure, with a central application template, but also be able to put code into the head of the document? Thanks for reading.
Add <%=yield :header %> in your HTML head. Then, in a view:
<% content_for :header do %>
<!-- Javascript here //-->
<% end %>
<!-- Rest of the page here //-->
The bit in the content_for block will render where your yield :header is in your template.

Resources