Active Navigation

Hey there,
I tried to integrate an active navigation menu, but none of the pages I found helped me. So I start this topic here. What I want to have is a navigation menu, that highlights the current page. So far so good. I have a layout.erb which designs my pages so I just have to fill it all with content and not create the whole site again and again and again. Some instructions I found with Google said, that I should create a individual navigation menu for every page with an active navigation for the current site. But my navigation menu is created in the layout.erb so this wonā€™t work. Another instruction said I should create this helper

    helpers do
  def nav_active(page)
    @page_id == page ? {:class => "Active"} : {}
  end
  def path(page)
    t("paths.#{page}")
  end
end

And the to use this

<li class="first"><%= link_to "Home", "/", title: "home", :class => ('active' if @home) %></li>

as navigation menu. But this still doesnā€™t work. Anything who could give me another instruction to make this navigation menu

<div id="primary_navigation">
          <ul>
            <li class="first"><%= link_to "Home", "/", title: "Home" %></li>
            <li><%= link_to "Link1", "/link1.html", title: "link1" %></li>
            <li><%= link_to "Link2", "/link2.html", title: "link2" %></li>
            <li><%= link_to "Link3", "/link3.html", title: "link3" %></li>
            <li><%= link_to "Link4", "/link4.html", title: "link4" %></li>
            <li><%= link_to "Link5", "/link5.html", title: "link5" %></li>
            <li class="last"><%= link_to "Link6", "/link6.html", title: "link6" %></li>
          </ul>
        </div>

an active navigation?
Thanks a lot and sorry if bad english, Iā€™m not as fit in english as I should/would be. But Iā€™m working on it :smiley:

Guess you got no answer here? Iā€™m trying like the devil to get some auto navigation involved with middleman.

Nope, no answer. I tried some more things Google found, but nothing works. If anybody knows how to do it, I would appreciate a guide or even a hintā€¦

@bennjoem Iā€™m currently trying to do this and Iā€™m looking at how emberjs did theirs. They used a helper. So far itā€™s not working for me but Iā€™ll need to look at it again later. Let me know how it goes.

Just though that might help.

UPDATE:
I had to tweak the helper a bit but it definitely works :smile: :wink2:

Iā€™ve got an idea. How about something like this:

def nav_link(name, url, options={})
  options = {
    class: "",
    active_if: url,
    page: current_page.url,
  }.update options
  a = options.delete(:active_if)
  active = Regexp === a ? current_page.url =~ a : current_page.url == a
  options[:class] += " active" if active

  link_to name, url, options
end

I did an experiment in a branch of my blog, it worked okay in development: https://github.com/epochwolf/epochwolf.com/commit/aff0b143806b2a09d8b3c9554079771922ed8d24

I just use a helper that checks current_page.url:

def nav_link(link_text, url, options = {})
  options[:class] ||= ""
  options[:class] << " active" if url == current_page.url
  link_to(link_text, url, options)
end

Thereā€™s not much to it. I feel like Iā€™m missing something.

1 Like

Thanks for the link to emberjs. I was able to modify and it works.

You are welcome. you might want to post your modification so others can benefit from it. Up to you though!

I like @epochwolfā€™s solution though.

I looked at emberjsā€™ solution which is this this:

  def link_to_page name, url
    path = request.path
    current = path =~ Regexp.new('^' + url[1..-1] + '.*\.html')

    if path == 'index.html' and name == 'about'
      current = true
    end

    class_name = current ? ' class="active"' : ''

    "<li#{class_name}><a href=\"#{url}\">#{name}</a></li>"
  end

My attempt to modify it is simply:

 def link_to_page name, url
   path = request.path
   class_name = (path == url) ? ' class="active"' : ''
   "<li#{class_name}><a href=\"#{url}\">#{name}</a></li>"
 end

Hope this helps, I was struggling to find an answer myselfā€¦

And here is something that works for ā€˜pretty urlsā€™

helpers do 
  def link_to_page name, url
    path = request.path
    current = false

    current = url + "/index.html" == path

    if path == 'index.html' and url =="/"
      current = true
    end

    class_name = current ? ' class="active"' : ''

    "<li#{class_name}><a href=\"#{url}\">#{name}</a></li>"
  end
end

Like Aupajo, Iā€™m also interested why you are working this around using big-guns like Ember. Iā€™m using a simple helper that outputs either a (for normal menu-item) or span (for active menu-item). This version is also I18n-aware and supports a separate title attribute for a link:

# insert active link menu-item <A>, or <SPAN> if itā€™s current page URL

def insert_menu_item(page_url, menu_text, title_attr=nil)
  page_url = '/' + I18n.locale.to_s + page_url if I18n.locale != I18n.default_locale
  if current_page.url == page_url
    return content_tag :span do menu_text end
  else
    return link_to menu_text, page_url, :title => (title_attr || menu_text)
  end
end

helpers do
def is_page_selected(page)
current_page.url == page ? ā€œselectedā€ : ā€˜ā€™
end
end`

<nav>
<ul>
	<li class="<%= is_page_selected("/") %>"><%= link_to("Home", "/") %></li>
	<li class="<%= is_page_selected("/about/") %>"><%= link_to("About", "/about/") %></li>
	<li class="<%= is_page_selected("/portfolio/") %>"><%= link_to("Portfolio", "/portfolio/") %></li>
	<% link_to '/' do %><%= image_tag("logos/logo.png", :class => "logo") %><% end %>
	<li class="<%= is_page_selected("/support/") %>"><%= link_to("Support", "/support/") %></li>
	<li class="<%= is_page_selected("/contact/") %>"><%= link_to("contact", "/contact/") %></li>
	<li class="<%= is_page_selected("/blog/") %>"><%= link_to("Blog", "/blog/") %></li>
</ul>
nav {

@include opacity(.9);
background: #F7F7EE;
box-shadow: 1px 1px 2px -1px #777777;
list-style: none;
margin-left: 0;
padding-left: 0;
position: fixed;
border-top: 3px solid $alert-color;
ul {
margin: 0;
padding: 0;
display: block;
line-height: 45px;
list-style: none;
li {
@include transition(border .2s);
float: none;
display: block;
width: 100%;
margin-left: .4em;
margin-right: .2em;
margin-bottom: 0px;
line-height: 45px;
a:hover {
color: $alert-color;
}
&.selected {
border-bottom: 3px solid $highlight;
a {
color: $alert-color;
}
}
}
}

ā€¦

Dear all!

After an update of middleman (3.3.13), slim (3.0.3) etc. options are not passed any more. I tested a lot, but could not find out what the problem is.

config.rb contains the following helper

def menu_link(link_text, url, options)
  options[:class] ||= "menu-link"
  link_to(link_text, url, options)
end

which is called as

= menu_link("link text", "url", {})

in my layout.slim file.

Has anyone a clue?

Thank you very much!

Sorry, this is an issue with the current version of middleman and I18N.

No problem with the helper.

Hereā€™s a new gem for marking up a current link with aria-current (which you can then use to style off of): https://github.com/thoughtbot/middleman-aria_current

As an example, below is a typical website navigation where we use
current_link_to for each link (using ERB):

<nav>
  <%= current_link_to "Home", "/" %>
  <%= current_link_to "About", "/about" %>
</nav>

Now, when you visit /about, the link for that page will be given the
aria-current attribute:

<nav>
  <a href="/">Home</a>
  <a href="/about" aria-current="page">About</a>
</nav>

You can then use a CSS attribute selector to style the current link:

[aria-current] {
  font-weight: bold;
}
1 Like

@tysongach, sorry, Iā€™m new to all this. I canā€™t seem to get this option to work.

<style> 
[aria-current] {
        font-weight: bold;
      }
</style>
<body>
<nav>
<%= current_link_to "Writing Principles", "01-writing-principles.html" %><br><br>
<%= current_link_to "Voice and Tone", "02-voice-and-tone.html" %>
</nav>
</body>

Any thoughts as to why it wouldnā€™t work?