I'm very new to rails and I want to have a banner that will dynamically change based on the page the user is on. Normally I would just have the banner image in the view for each page, however the client wants the banner to be above the navigation bar, and right now I have my navigation bar in my application.html.erb file. How would I go about doing this?
User a helper method.
In application.html.erb, in an appropriate spot, put something like:
<%= banner_helper %>
Then in a helper, define:
def banner_helper
image_to_use = switch "#{controller_name}_#{action_name}" do
when 'home_index'; 'homepage_banner.gif'
else 'some_other_image.gif'
end
content_tag :img, src: image_to_use, alt: 'some text'
end
Related
I want to show two different navbars. One will be displayed, on all pages except home page, when you're logged in. While the other navbar will be displayed just on my landing page.
I am thinking that I will probably need to write an if statement.
If (current user is not logged in) or maybe (current user is viewing home page) do
<nav>Second navbar</nav>
else
<nav>First navbar</nav>
end
I am very new to rails, so I could be wrong. (And yes, I know that's not how to correctly write an if statement in Ruby)
Home page is located at:
home/index.html.erb
I normally do following setup:
create partial shared/_nav_menu.html.erb
inside partial I put logic like:
<% if current_user %>
// nav bar for logged in user
<% else %>
// nav bar for non logged in users
<% end %>
Then inside application.html.erb file I render the partial like this:
<%= render :partial => 'shared/_nav_menu' if show_menu? %>
Inside my application_controller I put logic like this:
def show_menu?
true
end
helper method: show_menu?
If I don't want to show the menu for static_pages then inside static_pages_controller I overwrite show_menu? method to return false.
class StaticPagesController < ApplicationController
def show_menu?
false
end
helper_method: show_menu?
end
You don't have to use exactly this setup but I like this setup because my nav menu logic is kept seperate in partial. All logic required to nav menu lives in this file.
This approach don't bloat my application.html.erb file with lots of if..else.
In the case of two menus, but leaving yourself open to more, I would use a similar-but-slightly-different approach than Reboot's answer.
In the layout:
<%= render :partial => #nav_bar_partial %>
Then in my application controller, define the default nav:
def standard_nav
#nav_bar_partial = "path/to/standard/nav/partial"
end
From there, you can override that nav partial any time you need to (with any partial you want) from your controller
#nav_bar_partial = "path/to/new/nav/partial" if condition_that_requires_a_different_nav
That way, you have a little more flexibility. If for some reason you want to add a third nav bar for some other condition, you can just override the partial elsewhere without changing any of the above code.
You can prepare two layouts, one for the landing page and another for rest of the pages. Take a look at the official documentation: http://guides.rubyonrails.org/layouts_and_rendering.html.
How do you make a specific view show a different helper.
module ApplicationHelper
def about_title
%Q{Everything you need!}.html_safe
end
def contact_title
%Q{Contact us!}.html_safe
end
end
I have a partial header that renders in every view but I want to show a different header title without having to edit the views directly (or edit a variable? in the view to show what I want?)
<h1 class="title"><%= about_title %></h1>
What I'm thinking is making an if/else in the helper but I am new to rubyonrails and I'm not sure how is this done.
You need to set the title somewhere. There's a few ways you can handle this. You could use the controller + action name, and set up the titles in i18n.
en:
titles:
home_index: "Welcome!"
session_new: "Login"
Then in your layout:
<title><%= t("titles.#{controller.controller_name}_#{controller.action_name}") %></title>
Another way to do it is using content_for & yield but that means putting code in your views :)
I have link in a view , href on this link points to an action in a different controller.
What I need is when I click the link I need the view corresponding to a different controller to be rendered in my first views div.
eg:
I have a menu list in the left side of the page and a content div in the rightside of the page. Each of the left side menu corresponds to actions/views in different controllers.
when I click on any of the left side links it should render the respective htmls from that controller, in my right side div.
Thanks
The rails-y way of doing this is to use the remote: true option in your link_to. Setup the controller to respond to format.js, and setup a js.erb template to replace said content.
<%= link_to 'Page 2', page_2_path, remote: true %>
<div class="content"></div>
Controller:
class PagesController < ApplicationController
def page_2
end
end
Views:
# pages/_page_2.html.haml
<h1>Some content</h1>
# pages/page_2.js.erb
$('.container').html('<%= escape_javascript(render(partial: 'pages/page_2')) %>');
For the menu/page content feel you're looking for, Rails 4's turbolinks give a pretty good feel for what you want to achieve.
I have a tab navigation page in my rails app which is shared across all of my views. Inside I have a small text area which should change depending on the page that the user is on.
Currently I am doing this by adding a variable to the controller and using it in the render partial path, like so:
class Myapp::WebsitesController < MyappController
def set_up
#page = 'websites/left_text_info'
end
and then in my partial:
<%= render :partial => #page %>
This works but it doesn't feel like the best 'ruby' way of doing things. Can anyone advise on a better way of doing this?
Thanks
You can use controller_name helper method directly in your view and skip the controller part:
<%= render "#{controller_name}/left_text_info" %>
Or if the only thing that change is the content of the textarea, then perhaps the best way is to define a helper method that returns only the content for it, so you don't need multiple partial files that are very similar.
module ApplicationHelper
def text_area_content
case controller_name
when "users"
"content for users"
when "articles"
"content for articles"
else
"other content"
end
end
end
I'm using the same layout for several controllers, and inside this layout I include a menu using a call to a helper, like this:
<%= side_menu %>
What I'd like to do is vary the contents of side_menu depending on the controller that's invoking the layout. In an ideal world, I could define side_menu in application_controller.rb and in other helper files and then the appropriate helper would be selected depending on the controller; in other words, something like this:
# application_helper.rb
def side_menu
"generic menu This goes here"
end
# users_helper.rb
def side_menu
"menu for users goes here"
end
# guests_helper.rb
def side_menu
"menu for guests goes here"
end
This doesn't work because in Rails 3 all helper files are loaded and I have no control over which side_menu will actually be called. It would be great if there were an option to load only application_helper.rb and the controller-specific helper, but there's not one (yet).
What's the best way to vary the content of a helper depending on the controller? I'm currently defining side_menu once in application_helper.rb and then checking to controller to see what to add. This feels wrong, since the problem nearly screams for a subclass-and-override answer -- which I can't do due to the "helper :all" behavior of Rails 3. Suggestions?
You can define this method in controller and add:
helper_method :side_menu
But maybe different solution would be better. I think that you can add _side_menu.html.erb in each controllers view folder and when you call <%= render :partial => 'side_menu' %> it should look for different files depending on current controller (however rememeber to add this file for all controllers).
Or you can mix these two methods. Add this helper method to controller and inside it render right file. This way it is better, because you get some default side menu and it won't crash when there is no side menu partial for a controller.
You can also in layout add <%= yield :side_menu %> and if you want to put something in side menu, just add <% content_for :side_menu do %> bla bla bla <% end %>.