Okay, so I’m trying my hand at building a dynamic nav within Radiant
for the first time. The top nav is static and I used the navigation
tag for it. Though when someone clicks on one of the top links
potentially it could display sub links beneath it such as this when
the user has clicked the about us page:
About Us
- Faculty
- History
- Jobs
- Policies
Admissions
Calendar
Contact Us
Education
The problem is when I click on About Us all the sub links have the
about us page properties. I’ve tried several things with no better
results. My main approach has been to create a sub_nav page part in
my top level pages that I have the navigation tag use if selected.
Here’s the navigation tag:
<r:navigation urls=“About Us: /about_us/; Admissions: /admissions/;
Calendar: /calendar/; Contact Us: /contact_us/; Education:
/education/”>
<r:normal>
<r:title /></r:normal>
<r:here>
<r:title /><r:if_content
part=“subnav”>
<r:content part=“subnav” /></r:if_content></r:here>
</r:navigation>
For the sub_nav page part I’ve tried a few different things such as:
<r:children:each>
I noticed some comments on using the r:child in some cases so I tried
that:
<r:children:each><r:child>
Then I figured maybe I needed to explicitly find the about_us page such
as this:
<r:find url="/about_us">
<r:children:each><r:child>
So did I miss something basic or am I going down the wrong hole here?
Thanks for the help.
Cheers,
Marty
Marty,
The problem is that inside the <r:navigation> tag, the url
and
title
properties don’t belong to an actual page, but are the
information that you put in the urls
attribute of the tag. So you
could create a navigation link to a non-existent page, hypothetically.
Perhaps you need something that traverses the children of the top
page, then conditionally their children.
Sean
I wrote my own tag (wrapped in an extension) to do this Marty.
I’ll paste the code snips in here they may be able to help you out, if
you want more I could post a zip file somewhere.
Dynamically generates collection of links.
Very similar to ‘navigation’ w/some differences.
Pulls all children and adds parent first.
tag ‘dynamic_secondary_navigation’ do |tag|
hash = tag.locals.dynamic_secondary_navigation = {}
tag.expand
raise TagError.new(“dynamic_secondary_navigation' tag must include a
normal’ tag”) unless hash.has_key? :normal
result = []
fp = FantasticPage.new(tag.locals.page)
p = fp.top_level_page
pairs = Array.new
pairs << ['Overview', p.url]
for child in p.children
pairs << [child.title, child.url]
end
pairs.each do |title, url|
compare_url = remove_trailing_slash(url)
page_url = remove_trailing_slash(self.url)
hash[:title] = title
hash[:url] = url
case page_url
when compare_url
result << (hash[:here] || hash[:selected] ||
hash[:normal]).call
else
result << hash[:normal].call
end
end
between = hash.has_key?(:between) ? hash[:between].call : ’ ’
result.join(between)
end
Class that the tag above calls:
class FantasticPage
attr_accessor :page
Set the page.
def initialize(page)
@page = page
end
Returns ‘top_level_page’ one down from root.
NOTE: Only works for 2nd and 3rd level pages.
def top_level_page
url = @page.url
pieces = @page.url.split("/")
if pieces.size == 3
url = @page.parent.url
end
return Page.find_by_url(url)
end
end
On 2/8/07, Michael J. [email protected] wrote:
I wrote my own tag (wrapped in an extension) to do this Marty.
I’ll paste the code snips in here they may be able to help you out, if
you want more I could post a zip file somewhere.
Yeah, I think this is probably the road I need to go down. However, I
have to wonder, aren’t more radiant sites needing something like this?
I suppose you could do if_url matches but it would seem smarter and
simpler if you could just dynamically make nav off your existing pages
especially if you want to have a selected page’s sub nav to fit into
the main nav bar.
Michael, I would like to see more. Though I haven’t dived into any of
the radius code yet I would have to wonder if you take all the
children of a page, is there a simple way to filter out certain pages
such as by page type? For instance, I might not want certain pages to
be in the main nav such as contact us but would still want them off
the root that might be linked in the footer, for example. Another
example would be the css files off the root.
Does anyone else have a similar solution such as Michael’s out there?
Cheers,
Marty
Does anyone else have a similar solution such as Michael’s out there?
Here’s an example to build dynamic tree navigation:
http://pastie.caboo.se/39956
It produces:
http://pastie.caboo.se/39959
Hopefully, this inspires some ideas for you.
Layout/formatting is controlled in css.
BTW- Thanks Michael! for your post. It helped me while I worked on this
tree
navigation tag.
Todd
PS- I don’t like the hardcoding for ul, li, and css classes. It
wouldn’t be
that difficult to extract refactor the hardcode into configurable tag
attributes/nodes.
PS 2, Electric Boogaloo- I don’t understand while I had to call
options.dup, but
if I didn’t the value was being concatenated each time through the
getBranch
call.
I wanted to post a follow-up on my original email on building dynamic
navs. Thanks to the several folks who have posted their own
solutions. I chatted a couple times with Sean and came up with an
almost all snippet/tag solution. The only trick is I need this new
tag based on a recent patch by Sean that exposes the
tag.globals.actual_page. Here’s the tag:
tag “if_ancestor_or_self” do |tag|
tag.expand if (tag.globals.actual_page.ancestors +
[tag.globals.actual_page]).include?(tag.locals.page)
end
So this guy essentially will expand his contents if the current page
matches the comparing page or one of its parents.
Here is the snippet code that I use to build my left nav:
And the sub-nav snippet looks like this:
<r:unless_content part=“no-map”>
What all this builds is a nested unordered list of links found off the
root page. I filter out pages that I don’t want by putting a no-map
page part on them. This also plays nicely with Sean’s original
sitemap snippet. This pretty much meets my needs but it may also be
better expressed as its own tag. For one the html output has tons of
extra space as well as an empty
for the lowest level children.
Cheers,
Marty
to add my 2 cents to this conversation…
Uses all standart procedures besides the “parent” tag, which can be
added as shown here >
http://dev.radiantcms.org/radiant/wiki/HowToDefineGlobalTags
it basically uses the r:navigation tag, in conjunction with the r:parent
and r:children tag…to get all data needed
obviously you need to patch up the css if you want a vertical menu like
in my case
#navigation ul, ul {margin:0px; padding:0px; list-style: none;}
#navigation ul li {margin:0px; padding:0px; list-style: none; }
maybe this helps someone out
best
Flo,