In the spirit of The Rails Way Free-for-all (http://
www.therailsway.com/2007/6/4/free-for-all-tab-helper), I thought it
would be fun to see how we all handle making dynamic navigation for
Radiant sites.
PROBLEM: I have a hierarchical site, where each page has several
children, and some children also have children. I want a standard
left-hand navigation menu. It should be automatically generated. The
navigation menu should show the children for only the current page,
and it should expand to show the parents and ancestors of the current
page.
Example:
- Home
- About
- Articles
- Article 1 – you are here
- Article 2
- Widgets
- Hoozits
- Whatzits
(- expanded pages)
(+ unexpanded pages)
If you’ve done this in Radiant, please post your solution. See mine
in action at http://radiant.artofmission.com/ Username: demo,
password: radiant. Also see http://biola.artofmission.com (under
construction)
Pro:
- Easy & foolproof - content editors don’t even have to think about
navigation - it just happens for them. - Automatic - new pages show up in nav automatically.
Con:
- Slow as molasses. On http://biola.artofmission.com, regenerating a
page can take as long as 2 seconds.
Here’s my code:
== Snippets ==
=== Nav ===
-
<li class="current">Home
=== sub-nav ===
<r:unless_content part=“no-map”>
<li<r:if_self> class=“current”</r:if_self>><r:breadcrumb />
<r:if_children>
<r:if_ancestor_or_self>
<r:children:each>
<r:snippet name=“sub-nav” />
</r:children:each>
</r:if_ancestor_or_self>
</r:if_children>
== Tags ==
http://svn.artofmission.com/svn/plugins/radiant/plugins/navigation_tags
require ‘standard_tags’ # make sure we have the previous definition
first
module StandardTags
include Radiant::Taggable
Inspired by this thread:
http://www.mail-archive.com/[email protected]/
msg03234.html
desc %{
Renders the contained element if the current item is an ancestor
of the current page or if it is the page itself.
}
tag “if_ancestor_or_self” do |tag|
tag.expand if tag.globals.actual_page.url.starts_with?
(tag.locals.page.url)
end
desc %{
Renders the contained element if the current item is also the
current page.
}
tag “if_self” do |tag|
tag.expand if tag.locals.page == tag.globals.actual_page
end
desc %{
Renders the contained elements only if the current contextual
page has children.
*Usage:*
<pre><code><r:if_children>...</r:if_children></code></pre>
}
tag “if_children” do |tag|
children = tag.locals.page.children
tag.expand if children.size > 0
end
end