Navigation that highlights the current page

176 views
Skip to first unread message

tenable

unread,
Oct 27, 2009, 11:15:35 AM10/27/09
to nanoc
Thanks, man. I forgot about the Nanoc site! I found what I was looking
for - navigation that highlights the current page.

You have this in your layout:

<ul>
<li><%= nav_link_to_unless_current('home', '/')
%></li>
<li><%= nav_link_to_unless_current('news', '/news/')
%></li>
<li><%= nav_link_to_unless_current('about', '/about/')
%></li>
<li><%= nav_link_to_unless_current('tutorial', '/tutorial/')
%></li>
<li><%= nav_link_to_unless_current('manual', '/manual/')
%></li>
<li><%= nav_link_to_unless_current('migrating', '/migrating/')
%></li>
<li><%= nav_link_to_unless_current('community', '/community/')
%></li>
</ul>

and this in /helpers:

def nav_link_to_unless_current(text, path)
if @item_rep and @item_rep.path == path
"<span class=\"active\"><span>#{text}</span></span>"
else
"<a href=\"#{path}\"><span>#{text}</span></a>"
end
end

I'm still trying to fully understand @item, @item_rep, and @items.

Questions:
First of all, is it possible to loop through a set of items instead of
writing out every link?

<% @items.each do |item| %>
<li><%= nav_link_to_unless_current(item[:name], item.identifier) %></
li>
<% end %>

Why not use

if @item.identifier == path

in your helper?

So, basically when do you use @item vs @item_rep when writing helpers?
And how do you make collections of @items to loop through?

Denis Defreyne

unread,
Oct 27, 2009, 6:39:59 PM10/27/09
to na...@googlegroups.com
Hi,

On 27 Oct 2009, at 16:15, tenable wrote:

> I'm still trying to fully understand @item, @item_rep, and @items.

This morning I added a glossary to the manual on the nanoc web site.
You can find it at <http://nanoc.stoneship.org/manual/#glossary>; it's
probably a useful reference.

@item = the item that is currently being compiled
@items = the list of all items in the site
@item_rep = the item representation that is currently being compiled.

An item can have multiple representations (for example: HTML, XHTML,
JSON, …), but by default it only has one representation. An item'
identifier is not necessarily the same as an item representation's
path: an identifier could be /foo/ while a path could be /foo.html.
Routing rules give reps a path. A representation corresponds with a
single output file (or no output file at all, if the corresponding
routing rule returns nil).

> Questions:
> First of all, is it possible to loop through a set of items instead of
> writing out every link?
>
> <% @items.each do |item| %>
> <li><%= nav_link_to_unless_current(item[:name], item.identifier) %></
> li>
> <% end %>

This is possible, but the code should be changed a bit. You shouldn't
link to an item, but rather to a specific representation: after all,
if an item has multiple representations, which one should be linked
to? nanoc can't determine this by itself. So, the code should probably
be something like

<% @items.each do |item| %>

<li><%= nav_link_to_unless_current(item[:name], item.reps[0].path)
%></li>
<% end %>

In this case, the link will be made to the first representation in the
item's list of representations. This is fine if your items only have a
single representation (which is probably the case unless you've
manually added multiple representations). If you have multiple
representations and want to link to a specific one, you'll have to use
Enumerable#find on item.reps to get the representation you want.

> Why not use
>
> if @item.identifier == path
>
> in your helper?

Identifiers and paths are two separate things; they should preferably
not be mixed. Such code may seem to work fine in this case, but not
always.

Consider the following case (which you probably have in mind):

item identifier = /foo/
item rep path = /foo/ (not /foo/index.html because index.html is
stripped)

Here, everything will work fine. But now imagine a case where there is
a routing rule that creates output files like output/foo.html instead
of the default output/foo/index.html:

item identifier = /foo/
item rep path = /foo.html

The comparison will fail here…

> So, basically when do you use @item vs @item_rep when writing helpers?

If you want to access attributes, use @item. If you want to do
something specific with the output file, such as get its path, use
@item_rep.

> And how do you make collections of @items to loop through?

Not sure what you mean here. Could you elaborate?

Item representations are a powerful concept, but unfortunately they
sometimes are a bit confusing. If you think the documentation could be
cleared up, or if the nanoc API should be improved, don't hesitate and
let me know.

Regards,

Denis

--
Denis Defreyne
denis.d...@stoneship.org

tenable

unread,
Oct 28, 2009, 2:45:15 AM10/28/09
to nanoc
Ah, I see! I think the Nanoc wheels are starting to turn a little bit
haha

I'm going to be building a couple of sites with Nanoc in the next few
months and I'm sure I'll have plenty of more questions. So, to be
continued...

(p.s. This is way off-topic, but you mentioned Braid in one of your
posts on stoneship... sweet game! I was inspired to investigate other
independent games as well and I found Machinarium - also a sweet game
and very beautifully done like Braid. Definitely check it out if you
haven't already.)


Denis Defreyne

unread,
Oct 28, 2009, 4:50:56 AM10/28/09
to na...@googlegroups.com
On 28 Oct 2009, at 07:45, tenable wrote:

> Ah, I see! I think the Nanoc wheels are starting to turn a little bit
> haha
>
> I'm going to be building a couple of sites with Nanoc in the next few
> months and I'm sure I'll have plenty of more questions. So, to be
> continued...

Cool. :)

> (p.s. This is way off-topic, but you mentioned Braid in one of your
> posts on stoneship... sweet game! I was inspired to investigate other
> independent games as well and I found Machinarium - also a sweet game
> and very beautifully done like Braid. Definitely check it out if you
> haven't already.)

I bought Machinarium and it's great. I actually was thinking about
writing a Machinarium review, heh…

Reply all
Reply to author
Forward
0 new messages