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.
Related
I have a page in rails that has several partials rendered in it. I want many of those partials to have a link which will allow the user to print them. Currently, I can only get the print link to print the whole page rather than just the partial.
Is there a way to do this, or will I need the user to load a whole page before printing?
Edit:
I would like to have each partial have its own individual printing link. There are two many link_to lines I've tried using.
<%= link_to 'print ingredients', :partial => 'table_ingredients', :onclick => 'window.print();return false;' %>
The line above doesn't do anything when clicked.
<%= link_to 'print ingredients', 'table_ingredients', :onclick => 'window.print();return false;' %>
The line above prints the whole page.
I was lead to believe that the second argument for link_to was the page that should be printed.
I do it this way:
In my view I have a link like this:
<%= link_to 'Show Current Inventory Levels', parts_inventory_levels_path, :target => '_blank'%>
The :target => '_blank' causes it to open in a new tab/window
The parts_inventory_levels_path is in the routes.rb as:
get 'parts/inventory_levels' => 'parts#inventory_levels'
So it's going to the parts controller and calling the inventory_levels action which is:
def inventory_levels
#parts = Part.all.order(:name)
render 'inventory_levels', layout: "print_table"
end
Here's the key part, layout: "print_table". I have a layout file in my app/views/layout/ folder called print_table.html.erb:
<head>
<%= stylesheet_link_tag 'print', media: 'all' %>
<%= javascript_include_tag 'application' %>
<%= csrf_meta_tags %>
<%= yield(:head) %>
</head>
<body>
<%= yield %>
</body>
So the data from my controller action calls render on inventory_levels.html.erb:
<%= link_to_function('Print this Page', 'javascript:print()') %>
<br>
<table id="parts_table" class="table pretty" border='1'>
<thead>
<tr>
<th class="sortable">Name</th>
<th class="sortable">Sku</th>
...table omitted for brevity
Note the first line, it calls the javascript:print() function to print the page. The reason I render a separate page is I want to format that page in a very simple way that is better suited to printing. The nice thing is I am still able to use the table_sorter javascript to sort the table before I print it.
"I was lead to believe that the second argument for link_to was the page that should be printed." That is incorrect. The second part of the link_to is the path or url. Rails is interpreting your table_ingredients as
print ingredients
I don't know your controller name so I had to use a placeholder.
I could help you write the actual code but you should just be able to use what I have here applied to your code. But if you need more help please post your controller, and any applicable routes. You can probably reduce repetitive code by passing the same controller a value as to which partial you want to render (I am rendering a whole new page but the partial should also work). Also there is probably away to use AJAX.
In my quest to keep my application views as DRY as possible I've encountered a little snag. My appliation.html.erb incorporates a static sidebar menu. Each of my main controllers incorporates a secondary sidebar menu (essentially a submenu). I can take the code that renders the menu out of application.html.erb and put it in each of my views and change the secondary sidebar there, but this produces a lot repetition in my views.
I saw this SO post and looked at this page, but I was unable to get either idea to work. I was thinking that I could put something like:
<% provide(:submenu, 'layouts/sidebars/sidebar_customers_contacts') %>
at the top of each view and use that to render the associated partial by doing
<% content_for(:submenu) do %>
<%= render :partial => :submenu %>
<% end %>
from the application.html.erb but of course that didn't work.
This is my current application.html.erb:
<div class="side">
<%= render 'layouts/sidebar' %>
<%= render 'layouts/sidebars/sidebar_dashboard' %><!-- this needs to load a sidebar based on the controller that calls it. Each view of the controller will get the same sidebar. -->
</div>
<div class="main-content">
<%= yield %>
</div>
I feel like I'm making this more difficult than it really is. Is there a simple way to do this?
Rails provides a helper called controller_name which you can read more about here.
Assuming you adhere to your own naming conventions, this should work as-is. If you decide some controllers don't get a sidebar, you may need to throw in some conditionals...
application.html.erb
<div class="side">
<%= render "layouts/sidebar" %>
<%= render "layouts/sidebars/#{ controller_name }" %>
</div>
<div class="main-content">
<%= yield %>
</div>
EDIT
Sorry, my mistake was using single quotes instead of double-quotes. You cannot use #{string interpolation} within single quotes. Source
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
So I'm working on an open source project and due to different versions, there's the issue where I can't count on there being a controller for a view. Instead this email would be send out via a rake task for one version and a few others would done via a controller. Now you understand why I'm asking a bad practice question...
I have a layout for a view. Does anyone know a way to specify what the layout is for the view within the view. Some pseudo-code:
<%= extends 'layout/test_mailer` %>
<h1> Hey there! </h1>
And the layout would have the usual yield within it.
I hope I'm explaining the problem good enough.
<%= render partial: "hey_page", layout: "layout/test_mailer" %>
Check part 3.4.3 Partial Layouts at RailsGuides.
I think using yield and content_for should solve the problem. [Guides]
# my_layout.html.erb
<%= yield :mail_view %>
# my_mail_view.html.erb
<%= content_for :mail_view do %>
<!-- html -->
<% end %>
Of-course, if you are using params to get the layout, this would be a wrong answer.
Then, you can also use:
<%= render partial: "link_area", layout: "graybar" %>
You can use
//controller action
def index
render layout: test_mailer
end
//view, index.html.erb
<h1> Hey there! </h1>
//view, layout/test_mail.html.erb
<html>....layout for you test mail
<% yield %>
</html>
I am new to rails. I am having difficulty in understanding template inheritance. Earlier I have worked in django and seen template inheritence there. There I saw child is told about parent using "extends" command. Can anyone explain how it works here. I have gone through guidelines of ruby but it was not clear.
Thanks
It's quite simple to do in Rails.
You simply tell the template you are currently rendering to render another template.
For example layouts/application.html.erb contains something like this:
<% content_for :navigation do %>
<nav>...</nav>
<% end %>
<% content_for :content do %>
<%= yield %>
<% end %>
<%= render :template => 'layouts/main_application' %>
The important part is the render :template part that then delegates this template to also render the layouts/main_application.html.erb that in my case looks something like this:
<header>
...
</header>
<body>
<%= yield :nav %>
<%= content_for?(:content) ? yield(:content) : yield %>
</body>
What I am doing here is having a main template that does not contain the navigation (for things like login etc) and the application.html.erb adds that navigation to the :nav content placeholder.