Radiant Free-for-all: Navigation Menus

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:

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

 Are you running radiant/rails through CGI?

/AITOR
 Are you running radiant/rails through CGI?

No, it’s running on Mongrel.

I’ve been benchmarking the script - the slowness is coming from
recursively calling <r:snippet name=“sub-nav” />. Each time the sub-
nav snippet is called takes about 0.05 - 0.1 seconds. For a large
site, that adds up to a very slow load time. I’m not sure yet if it’s
rendering the snippet that takes so long, or if it’s my tag that’s
inefficient.

On Jun 22, 2007, at 3:41 AM, Aitor Garay-Romero wrote:

In the spirit of The Rails Way Free-for-all (http://

navigation - it just happens for them.
=== Nav ===

desc %{
current page.

<r:if_children>…</r:if_children>



Ryan H.
Art of Mission, Inc.
3720 Gattis School Rd #800 PMB 245
Round Rock, TX 78664

800-722-1492 (phone)

www.artofmission.com
[email protected]

One thing John and I discussed last night in a “duh!” moment was the
fact that there is not an index on the ‘parent_id’ column of the pages
table. Adding that might give a minor performance boost.

Sean

Wow, this is a good idea. I will try adding an index and see if it
helps.

On Jun 22, 2007, at 8:29 AM, Sean C. wrote:

site, that adds up to a very slow load time. I’m not sure yet if it’s


Ryan H.
Art of Mission, Inc.
3720 Gattis School Rd #800 PMB 245
Round Rock, TX 78664

800-722-1492 (phone)

www.artofmission.com
[email protected]