# Navigation Tags help

**URL:** <https://www.ruby-forum.com/t/navigation-tags-help/106352>\
**Category:** Radiant CMS\
**Created:** [June 8, 2007, 10:18pm UTC](https://www.ruby-forum.com/t/navigation-tags-help/106352 "2007-06-08T22:18:19Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![rpheath](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/73ab20/32.png) [@rpheath](https://www.ruby-forum.com/u/rpheath)\
**Post date:** [June 8, 2007, 10:18pm UTC](https://www.ruby-forum.com/t/navigation-tags-help/106352/1 "2007-06-08T22:18:19Z")

</div>

Hi folks,

I have a set of navigation tags here:  
[http://svn.artofmission.com/svn/plugins/radiant/plugins/](http://svn.artofmission.com/svn/plugins/radiant/plugins/)  
navigation\_tags/

Basically, it lets you build nested navigation like you see here:  
[http://radiant.artofmission.com/blog/](http://radiant.artofmission.com/blog/)

The idea is to expand the navigation below the page that you’re  
currently on. So if you’re on the “About” page, you see only the two  
top-level items, but if you go to the “Blog” page, you see that  
page’s sub-pages in the nav.

The trouble is that the tags are very slow - rendering the page can  
take as long as 2-3 seconds on a big site. (Once the page is cached,  
it loads very quickly of course.) If anyone would like to help me  
figure out how to make this work faster, your help would be much  
appreciated!

Here are the snippets that I use to generate that navigation:

SNIPPET: nav

SNIPET: sub-nav  
\<r:unless\_content part=“no-map”\>  
\<li\<r:if\_self\> class=“current”\</r:if\_self\>\>\<r:link /\>  
\<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\>

As far as I can tell, it’s the “if\_ancestor\_or\_self” tag that’s  
slowing it down. Here is the content of navigation\_tags.rb:

module StandardTags  
include Radiant::Taggable

# Inspired by this thread:

# [http://www.mail-archive.com/removed\_email\_address@domain.invalid/](http://www.mail-archive.com/removed_email_address@domain.invalid/)

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.ancestors +  
[tag.globals.actual\_page]).include?(tag.locals.page)  
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

---

<div class="post-metadata">

**Author:** ![rpheath](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/73ab20/32.png) [@rpheath](https://www.ruby-forum.com/u/rpheath)\
**Post date:** [June 8, 2007, 10:24pm UTC](https://www.ruby-forum.com/t/navigation-tags-help/106352/2 "2007-06-08T22:24:20Z")

</div>

One optimization you might be able to make to the if\_ancestor\_or\_self  
(which normally could result in tons of DB calls) is to match the URL of  
the page in the iteration against the actual page. If the first part  
matches, then expand. Of course, this breaks if your site gets complex  
– virtual pages and such are the usual culprits.

tag ‘if\_ancestor\_or\_self’ do |tag|  
tag.expand if  
tag.globals.actual\_page.url.starts\_with?(tag.locals.page.url)  
end

Cheers,

Sean
