I have a controller method with custom layout and I cannot access the instance variables on corresponding views.
When I changed back to the default application layout. I can access the instance variables.
pages_controller.rb
def payment_summary
render layout: "content"
if session[:new_company_id].present?
#company = Company.find(session[:new_company_id])
end
#var = "this is test"
end
payment_summary.html.erb
<div class="row">
<div class="col-sm">
Company Info
<div class="card">
<%= #company.name %>
<%= #var %>
</div>
</div>
<div class="col-sm">
Due Today
</div>
</div>
layouts/content.html.erb
<!DOCTYPE html>
<html>
<head>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
<!-- Font Awesome 5 Free -->
<script src="https://kit.fontawesome.com/9da10782cc.js"></script>
<!-- for js cookie use -->
<script src="https://cdn.jsdelivr.net/npm/js-cookie#2/src/js.cookie.min.js"></script>
</head>
<body class="content-pages <%= body_class %>">
<%= yield %>
</body>
</html>
When I remove, render layout content everything works fine.
render in this case is "order dependent". Move it down, as the last statement within your action body:
def payment_summary
if session[:new_company_id].present?
#company = Company.find(session[:new_company_id])
end
#var = "this is test"
render layout: "content"
end
Related
I have a scaffold generated index.html.erb and am wondering if it is okay that is does not have basic HTML structure?
This is my code:
<% provide(:title, "Signing Up") %>
<h1>Signing Up</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(:reader, url: readers_path) do |f| %>
<%= f.label :email %><br>
<%= f.email_field :email, class: 'form-control' %>
</p>
<p>
<%= f.label :password %><br>
<%= f.password_field :password_digest, class: 'form-control' %>
</p>
<%= f.submit "Signing Up", class: "btn btn-primary" %>
<% end %>
</div>
</div>
I don't see usual HTML, <body>, <head> tags etc. Can I add it or is it not necessary?
It isn't necessary. In Rails, you have an application.html.erb file under views/layouts. This is used as a default for rendering any page.
This file is where you will see the usual HTML structure (DOCTYPE, head, body etc).
To find the base layout, Rails will look for a file in app/views/layouts with the same base name as the controller.
For example, rendering actions from the PostsController class will use app/views/layouts/posts.html.erb.
If there is no such controller-specific layout, Rails will use app/views/layouts/application.html.erb which is what is happening when you generate the scaffold.
This is what the application.html.erb looks like generally on a fresh project:
<!DOCTYPE html>
<html>
<head>
<title></title>
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %> #Content from the views is shown
</body>
</html>
See the docs for more information
in my current Rails app, I have a partial in my layouts folder for a navigation sidebar. I would like this sidebar to render for every page of my app except the new and thankyou actions of my score controller, because those two views are going to be a part of an iframe. To do this, I'm making another layout called iframe.html.erb where I'd like to put the logic to exclude the navigation sidebar.
Here is my application.html.erb layout file
<!DOCTYPE html>
<html>
<head>
<title>NPS</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
<div id="wrapper">
<%= render 'shared/navigation' %>
<%= yield %>
</div>
</body>
</html>
And here is my iframe.html.erb file
<!DOCTYPE html>
<html>
<head>
<title>NPS</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
<div id="wrapper">
<%= if (current_page?(controller: 'scores', action: 'new') || current_page?(controller: 'scores', action: 'thankyou' )) do %>
<%= yield %>
<% end %>
</div>
</body>
</html>
I initially just had an unless statement in my application layout but that wouldn't work on the sign-in page because devise would be looking for those scores views in the devise folder. I'm also not very good with html.erb so I'm sorry if it's just a syntax thing.
Edit:
Here is the error I get with devise
ActionController::UrlGenerationError at /users/sign_in
No route matches {:action=>"new", :controller=>"devise/scores"}
Thanks
in your application.html.erb...
<%= render 'shared/navigation' unless #disable_nav %>
Then in your score controller where you have you have your two views...
def new
#disable_nav = true
# ...
end
def thankyou
#disable_nav = true
# ...
end
You don't need two layouts for that and your syntax is incorrect. Remove iframe.html.erb.
There are several ways to do it. Try this one in application.html.erb:
<div id="wrapper">
<% if !current_page?(controller: 'scores', action: 'new') && !current_page?(controller: 'scores', action: 'thankyou') %>
<%= render 'shared/navigation' %>
<% end %>
<%= yield %>
</div>
It should just work. However, it can be improved. Move this logic into your application_helper.rb:
def should_show_navigation?
!current_page?(controller: 'scores', action: 'new') &&
!current_page?(controller: 'scores', action: 'thankyou')
end
And then, in your layout file (application.html.erb):
<div id="wrapper">
<% if should_show_navigation? %>
<%= render 'shared/navigation' %>
<% end %>
<%= yield %>
</div>
It gets more readable.
I've finally found a beautiful theme that I'd like to use, and now I'm wanting to try something here. The main page is basically one background, and the contents of the page (aside from the page header) is inside of a white backgrounded area.
Therefore, I'm wanting to know if I can actually only show the page header outside of this specific area and render the rest of the contents inside of the specific area.
Here's an example of my layouts/application.html.erb file:
<!DOCTYPE html>
<html>
<head>
<title>Subzero</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag "application", params[:controller] %>
<%= csrf_meta_tags %>
</head>
<body>
<%= render "layouts/navbar" %>
<div id="main" role="main">
<%= render 'layouts/ribbon' %>
<div id="content">
<div class="row">
<div class="col-xs-12 col-sm-7 col-md-7 col-lg-4">
<h1 class="page-title txt-color-blueDark">
Wanting to put page title here.
</h1>
</div>
</div>
<div class="well">
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %>"><%= value %></div>
<% end %>
<div class="container">
<%= yield %>
</div>
</div>
</div>
</div>
<%= render "layouts/footer" %>
</body>
</html>
Rails lets you have several named yields in addition to the "main" yield.
To create a named yield call yield with a symbol identifying the slot:
yield :title
To add content to the slot you would use content_for.
content_for :title, 'Hello World!'
One cool trick is that you can declare a yield in your layout and then assign the content when your main yield renders:
app/views/layouts/application.html.erb:
<header>
<%= yield :header %>
</header>
<div id="main">
<%= yield %>
</div>
app/views/foo/show.html.erb:
<% content_for :header do %>
<h1>Hello from "foo/show"</h1>
<% end %>
<p>This is the main content</p>
This would render:
<header>
<h1>Hello from "foo/show"</h1>
</header>
<div id="main">
<p>This is the main content</p>
</div>
Another alternative is to use instance variables:
def new
#title = 'Hello World'
end
Which you would print in your layout:
<%= #title || "Welcome to my rails app" %>
The latter is a bit more flexible for simple strings like a page title since content_for cannot be called from your controllers (well kind of). While content_for is a powerful tool for creating dynamic chunks in your layouts and views and can even be used to set up a sort of inheritance in your views.
Not sure if this is a "best practice" way of doing it, but basically I added a function in helpers/application.html called function which looks like this:
#helpers/application.html.erb
def pg_header(header)
#page_header = header
end
and in my view, I have something that looks like this:
<% pg_header("Here's my page header") %>
And in my layouts/application.html, it calls #page_header since I don't think I can access any variables in the view until %yield% is issued. Not 100% sure but this is working for me. Any better solutions would be great. Thanks guys.
Is it possible to load a partial based on a parameter that is coming through a route? I've created a landing page template, and I'd like to tweak the main messaging a little bit based on industry. To complicate matters, the parameter needs to be optional.
For instance, if the URL is
www.domain.com/medical I want to render the partial landing/medical within layouts/header.html.erb which is rendered in layouts/application.html.erb
www.domain.com/legal I want to render the partial landing/legal within layouts/header.html.erb which is rendered in layouts/application.html.erb
www.domain.com renders the default partial landing/default.html.erb
Here's an example of my current views:
landing/medical.html.erb
<div class="heading">
<h1>Are you HIPAA Compliant?</h1>
Find out more by signing up below...
</div>
landing/legal.html.erb
<div class="heading">
<h1>Your Legal Practice needs help</h1>
<p class="leadFind out why by by signing up below...
</div>
landing/default.html.erb
<div class="heading">
<h1>What are you doing?</h1>
Probably nothing...
</div>
layouts/header.html.erb
<div class="heading">
<%= render 'the/optional/partial' %>
</div>
layouts/application.html.erb
<!DOCTYPE html>
<html>
<head>
<title><%= full_title(yield(:title)) %></title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
<%= render 'layouts/shim' %>
<% if content_for?(:head) %>
<%= yield(:head) %>
<% end %>
</head>
<body>
<div class="site-wrapper">
<div class="site-wrapper-inner">
<%= render 'layouts/header' unless #disable_heading %>
<div class="cover-container">
<div class="inner cover">
<%= yield %>
</div>
</div>
</div>
<%= render 'layouts/footer' %>
</div>
<%= debug(params) if Rails.env.development? %>
</body>
</html>
Is this possible?
I think some info is missing and it probably can lead to different ways to do it.
You can specify the parameter in the route:
routes.rb
get '/(:industry_param)' => 'welcome#index'
With this, assuming your website root is going to that route you will have now access to a variable params[:industry_param] that you can use to conditionally render the corresponding template:
welcome_controller.rb
#industry = params[:industry_param] || 'default'
layouts/header.html.erb
<div class="heading">
<%= render "landing/#{#industry}" %>
</div>
I think you can start from this. Have some security considerations like filtering the parameter in the controller and only accepting certain values, etc.
I'm trying to add a title tag to my website using ROR.
After adding the desired changes to ... in aplication.html.erb, then commiting and deploying it, I still do not see the complete title tag present with the changes I just made when I view the website on search results.
Why is this the case and is there anything I am forgetting to include?
<!DOCTYPE html>
<html>
<head>
<title>Website Name - Desired title tag added here but doesn't show in search results</title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<%= render 'shared/user_info' %>
</head>
<body>
<div id="body-interior">
<%= render 'shared/header' %>
<div class="container">
<% flash.each do |name, msg| %>
<%= content_tag(:div, msg, class: "alert alert-info") %>
<% end %>
<%= yield %>
</div>
<%= render 'shared/footer' %>
</div>
<%= render 'shared/final_scripts' %>
</body>
</html>
Thanks!
When you say search results, I assume you mean search engines like Google? If so, you need to know that changes like these won't be recognized instantly by Google. The changes should be visible as soon as Google (or any other robot) crawls the page in question again.
As far as I know you can force this process with Google's Webmaster Tools.