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.
Related
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
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
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.
I am new to Rails, can you check my code to see where I might be going wrong. I am attempting to create a Song object.
By looking at my SQLite File, I can see that no new songs are being created.
In views/songs/new.html.erb
<!DOCTYPE html>
<html>
<head>
<title>MusicDiscoveryApp</title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<%= form_for(#song, :html => {:id => 'add-to-library', :method => :post}) do |f| %>
<div class="item-info">
<%= f.select :category_id, [['Pop', 1], ['Rock', 2], ['Rap', 3], ['Reggae', 4], ['Other', 5]] , {:prompt=>"Select A Category"}, :id=>"choose-category"%>
</div>
<div class="item-info">
<%= f.text_field :name , :placeholder=>"Song Name"%>
</div>
<div class="item-info">
<%= f.text_field :price, :placeholder=>"Price"%>
</div>
<div class="item-info">
<%= f.text_area :details ,:placeholder=>"Details"%>
</div>
<div class="item-actions">
<%= f.submit "Post to Songs Library", :class=>"add-song"%>
</div>
<% end %>
</body>
</html>
The 'new' method from songs_controller.rb - it was automatically generated
def new
#song = Song.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #song }
end
end
The 'create' method from songs_controller.rb - also automatically generated
def create
#song = Song.new(params[:song])
end
Thanks for your time, I hope you can explain to me what I did wrong here. Thanks once again.
The song isn't being saved. Add:
#song = Song.new(params[:song])
#song.save
to your controller create method or change new to create
#song = Song.create(params[:song])