I am trying to use a basic current_page method to define whether a navigation link should be highlighted as the current page or not.
I am not receiving any errors at the moment but am clearly not defining things properly as it's not using my CSS correctly.
In my PagesController I have the following:
def current_page
current_page = (path)
end
and I am using an if and else statement on my pages view to try and define which CSS line to use which looks like this:
<div id="nav">
<ul>
<li>
<% if "current_page" %>
About
<% else %>
About
<% end %>
</li>
</ul>
</div>
I have read quite a few forums on this but still can't seem to get it right.
Mhh you got an error in your code. With if "current_page" you will get always true, and only the first link will get rendered. You should use if current_page instead.
But rails has a build in helper, called current_page? for exactly this purpose:
Just do it like this:
<% if current_page?(path) %>
About
<% else %>
About
<% end %>
See here for more information on current_page?
The klump's answer follows your requirement, but I dare to propose a different approach:
<div id="nav">
<ul>
<li>
<%= link_to_unless_current 'About', about_path %>
</li>
</ul>
</div>
This way your About will appear as a text if current page is about_path and as a link on any other.
About
Related
So im still very new to ruby on rails and what Im trying to do here is very simple. Im trying to create a facebook like app where if you click on the profile picture of a post it will direct you to the users profile page. I have just done something really similar in a online course but I cant seem to get this one to work in another view. Here is what I have that works in my header, navbar.
NAVBAR
<nav class="navbar navbar-default navbar-fixed-top">
......
<li><%= link_to "Show Profile" ,
user_profile_path(current_user.id, current_user.full_name) %></li>
....
</nav>
This code works and directs me to the corresponding users profile page.
Routes
Rails.application.routes.draw do
....
root 'statuses#index'
get '/:id/:full_name', to: 'profile#show' , as: :user_profile
.....
end
Problem View
<div class="page-header">
....
<% #statuses.each do |status| %>
<div class="row">
<div class="col-md-1">
<%= link_to image_tag(status.user.avatar.url(:thumb),
user_profile_path(status.user.id, status.user.full_name)) %>
//the above is what gives me the error in the title.
</div>
<% end %>
I have done my fair share of searching around and it seems that this error occurs if im passing in strings when it accepts hashkeys? Im not entirely sure. If there is a better way to do this that I should use please show me as I am very new and open to learning.
You have a wrong usage of a link_to helper. Instead of:
<%= link_to image_tag(status.user.avatar.url(:thumb), user_profile_path(status.user.id, status.user.full_name)) %>
^first argument ^second argument
Use:
<%= link_to user_profile_path(status.user.id, status.user.full_name) do %>
<%= image_tag(status.user.avatar.url(:thumb)) %>
<% end %>
As you can see, you pass _path helper as the second argument to the image_tag, this is wrong. The second argument to the image_tag should be a hash, thats why you have a undefined method 'symbolize_keys' for errors.
What is the best approach of dealing with class="active" problems in Rails?
I've found how to deal with this for single links, but when classes has to be set to "active" in different parts of the template, how do one deal with this?
Here is my code:
module AdminHelper
def nav_link(link_text, link_path)
class_name = current_page?(link_path) ? 'active' : nil
content_tag(:li) do
link_to link_text, link_path, :class => class_name
end
end
def active_section(section)
request.fullpath.start_with?(section)
end
end
And in the layout holding the menu:
<% if active_section('/superadmin') %>
<li class="active">
<% else %>
<li>
<% end %>
<i class="fa fa-asterisk fa-fw"></i> Superadmin <span class="fa arrow"></span>
<ul class="nav nav-second-level">
<%= nav_link 'Add Account', superadmin_new_account_path %>
<%= nav_link 'List Accounts', superadmin_list_accounts_path %>
</ul>
</li>
That is, I need to check if I am at a specific part of the url structure, and outputting the li class="active" in case of that. Otherwise just outputting the li element without class. I am using a menu; MetisMenu and needs to set this class so correct section is expanded.
My code works but it feels horrible wrong way to do it.
Would be really happy if someone can give a hint on how to do this the right way!
I recommend using simple-navigation gem
Not to be 'that guy', but have you looked into HAML? It makes doing conditional classing a ton easier. It also reads/looks much cleaner. i.e.
%li{:class => ("active" if active_section('/superadmin'))}
I am trying to insert content on my page with yield but every time action removes whole content from the page. I have one main yield which is working fine:
<body>
<%= render 'layouts/header' %>
<div class="container">
<%= yield %>
<%= render 'layouts/footer' %>
</div>
</body>
But inside that new content which is displayed on one page I have another yield:
<div class="container">
<%= render 'admins/menu' %>
<%= yield :admin %>
</div>
When user clicks on the menu which is rendered, new content should be displayed below that menu.
admins/_menu.html.erb
<div class="navbar">
<div class="navbar-inner">
<div class="container">
<ul class="nav">
<li><%= link_to "Users", :controller => "admins", :action => "test" %></li>
<li><%= link_to "1", ... %></li>
<li><%= link_to "2", ... %></li>
<li><%= link_to "3", ... %></li>
</ul>
</div>
</div>
</div>
Controller:
class AdminsController < ApplicationController
def index
end
def test
#users = User.paginate(page: params[:page])
end
end
test.html.erb
<% content_for :admin do %>
<h1>All users</h1>
...
<% end %>
When I click on the option 'Users' from menu, page refreshes, menu disappears and nothing is displayed inside `body'. I want the content to be displayed below menu. How to use that second yield and accomplish this functionality?
I hope the question is not confusing. If question is confusing, please write me in comments and I will edit it immediately.
Thank you :)
So, when you go to the index page you will get the piece of html that will be placed in the main layout, and this piece of html look like this:
<div class="container">
<%= render 'admins/menu' %>
<%= yield :admin %>
</div>
This code will yield :admin properly.
When you go to the test page you do not have this html code anymore (since it only belongs to the index method). So, anything you put in the content_for(:admin) block will be ignored since no-one is printing it.
What you probably want to do is creating a shared layout for all your admin pages. Follow this guide and you'll have your solution.
Solution
Edit the application.html.erb layout using this:
<%= content_for?(:content) ? yield(:content) : yield %>
instead of
<%= yield %>
Then create an admins.html.erb file inside the layouts folder to handle your admin pages' layout. Something like this:
<% content_for :content do %>
<div class="container">
<%= render 'admins/menu' %>
<%= yield %>
</div>
<% end %>
<%= render template: "layouts/application" %>
Will do fine. Then in the index.html.erb and test.html.erb just place regular HTML content, without using the content_for(:admin) block. Everything should work fine and you'll have your custom admin template, with a slightly different look from regular pages.
Calling yield doesn't work in helper modules, while content_for does, so you should replace your yield calls in the helper files.
Also noteworthy: using provide is recommended over content_for when you're only using the method in 1 place instead of multiple places. You'll get better performance since it won't leave the buffer open while looking for more content, and your intent will be clearer to other developers that may see your code. (see http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html#method-i-provide)
I found that you have to add an yield (without actually outputing) before the namespaced tags.
<div>
<% yield %>
<div class="mt-3">
<div class="text-2xl tracking-wide font-bold text-gray-900">
heading
<%= yield :heading %>
</div>
</div>
<div class="relative bg-white rounded-xl shadow-xl mb-8 min-h-28">
<%= yield %>
</div>
...
I am working on a Rails 4 project where I would like a different link to appear on the navigation bar depending on the current page. This is how I am trying to set it up:
<ul>
<% if current_page?("/company") %>
<li>Company Space</li>
<% elsif current_page?("/user_page") %>
<li>User Space</li>
<% else %>
<% end %>
</ul>
I know I've written this part correctly, because when I put it in the application.html.erb layout page, it works just fine. When I put the same exact thing in the top nav bar, however, it doesn't work. The nav bar is in a partial called _header.html.erb which is currently rendered in the layout as follows:
<body>
<%= javascript_include_tag "application" %>
<%= render 'layouts/header' %>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= yield %>
<%= render 'layouts/footer' %>
</body>
I assume this has something to do with the nav bar not detecting the current page. I am hoping someone can tell me why this is happening, and ideally I would like to find a relatively DRY solution that would allow me to have this feature. (I have thought of creating separate partials for the different conditions, and then putting the logic for displaying the partial in application.html.erb, but given that this is far from the only content in the nav bar, the maintainability of that seems quite dismal.)
Thanks for any help!
To expand upon nathan's answer, specify action
<% if params[:action] == 'company' %>
<li>Company Space</li>
<% else params[:action] == 'user_page' %>
<li>User Space</li>
<% end %>
This will work... but it doesn't feel like the cleanest way. Perhaps go about doing it with JS for it to be cleaner?
<% if params[:controller] == 'company' %>
<li>Company Space</li>
<% else params[:controller] == 'user_page' %>
<li>User Space</li>
<% end %>
you can make it more cleaner by moving the following to respected helper file.
def nav_bar_content(action)
if action == 'company'
"Company Space"
elsif action == 'user_page'
"User Space"
else
# statement
end
end
and call <li><%= nav_bar_content(params[:action]) %></li> this is on your nav bar
I am trying to set an li class of active based on what page the user is on.
I have 4 navigation elements and they all look something like this:
<% if #activeLi == "home" %>
<li class="active">
<% else %>
<li>
<% end %>
<%= link_to :controller => "home" do %>
<span>Home</span>
<% end %>
</li>
and then in each controller I just set #activeLi like this:
def index
#activeLi = "about"
end
I know this is pretty basic stuff, but i'm just wondering if there is an easier way to do this?
Well I know one way you can simplify this and thats by getting rid of the need to use those nasty instance variables.
<li class="<%= controller_name == "home" ? 'active': '' %>">
<%= link_to :controller => "home" do %>
<span>Home</span>
<% end %>
</li>