Radiant site map

Does anyone know of a way to generate a complete site map for a
Radiant powered site (all children, sub-children, etc.)? The
acts_as_tree that controls the site heirarchy only seems to be able to
query the immediate children of a node, and I can’t seem to work out a
recursive function that would do the job … any help would be
appreciated!

Nathan W. wrote:

Does anyone know of a way to generate a complete site map for a
Radiant powered site (all children, sub-children, etc.)? The
acts_as_tree that controls the site heirarchy only seems to be able to
query the immediate children of a node, and I can’t seem to work out a
recursive function that would do the job … any help would be
appreciated!

You could create a tag or set of tags on a behavior to do this for you.
What would you like to do? Create a nested unordered list?

Try this:

class SiteMapBehavior < Behavior::Base

 register "Site Map"

 define_tags do
   tag "tree" do |tag|
     page = tag.locals.page
     tree_for(page)
   end
 end

 private

   def tree_for(page)
     list = ""
     page.children.each do |child|
       list << "<li><a href="#{ child.url }">#{ child.title }</a>#{
         tree_for(child) }</li>"
     end
     "<ul>#{ list }</li>" unless list.empty?
   end

end

And then on the page part:

<r:find url=“/”><r:tree /></r:find>

The code above is completely untested, but should get you going in the
general direction.

Hope that helps.


John L.
http://wiseheartdesign.com

John W. Long wrote:

The code above is completely untested, but should get you going in the
general direction.

There were a few typos:

class SiteMapBehavior < Behavior::Base

 register "Site Map"

 define_tags do
   tag "tree" do |tag|
     page = tag.locals.page
     tree_for(page)
   end
 end

 private

   def tree_for(page)
     list = ""
     page.children.each do |child|
       list << %{<li><a href="#{ child.url }">#{ child.title
         }</a>#{tree_for(child) }</li>} unless child.virtual?
     end
     "<ul>#{ list }</ul>" unless list.empty?
   end

end


John L.
http://wiseheartdesign.com

Thank you John. These behaviour “pearls” from you are very useful for
a modest user like me … :slight_smile:

A couple of things … first, you are my hero … it worked
perfectly! This was the last bit keeping me from finishing a site.
Thank you (ad nauseam). Second, it’s at times like these that I wish I
understood better how things work inside of radiant.

If you have time, could you explain briefly what is “tag.locals” is?
For instance, when I call

raise tag.inspect

I get a dump of all parts of all pages on the site. Calling

raise tag.locals.inspect

seems to call a sub-set of the same information, but with no
distinguishing rhyme or reason (on my site, using the above raise
dumps the page for the site map, the home page, and the news and
events page, but no other pages).

Also, the “secret sauce” behind the sitemap behavior seems to be in
the “child.virtual?” declaration. Can you explain what the “virtual”
method is?

Thanks, and thanks again for the sitemap behaviour!

To add the home page to the site map, I simply replaced the line

tree_for(page)

with the line

%{

  • #{page.title}#{tree_for(page)}
}

A word of note: the site map behavior doesn’t create a link for the
home page …

Nathan W. wrote:

A couple of things … first, you are my hero … it worked
perfectly! This was the last bit keeping me from finishing a site.
Thank you (ad nauseam).

Awesome.

Second, it’s at times like these that I wish I
understood better how things work inside of radiant.

If you have time, could you explain briefly what is “tag.locals” is?

Tag#locals is sort of like scope for tags. Think of it as where you
define local variables for a tag. There is also the corresponding
Tag#globals which is for defining and using variables that you want
accessible to all tags.

See the Radius Quickstart guide for more info:

http://radius.rubyforge.org/files/QUICKSTART.html


John L.
http://wiseheartdesign.com