Alphabetical navigation

Hello,

We use the NavTree and Navon system in a fairly conventional way, to do top and left navigation panels. The order that links are displayed in these navigations panels is determined by editing the order of navons in the “Nav Submenu” slot of the NavTree (for the top nav) and navons (for each left nav in each section and subsection of the site.)

We would now like to augment these navigation panels with A-Z indexes in the footer of each page, and in a site directory. But I cannot find a way to list navons alphabetically by their displaytitle. The sys_ManagedNavContentFinder content finder, as used in the rffNav slot, does not have an order_by parameter. And $nav.root.getNodes(“nav:submenu”) returns an object of type com.percussion.utils.jsr170.PSNodeIterator. I cannot find any documentation on the methods available to PSNodeIterator objects, but it does not seem to be sort-able.

Does anyone have any ideas?

Thanks,

Andrew.

What’s wrong with using a JCR Query: select… from rx:rffNavon where jcr:path like … order by rx:sys_displaytitle

I thought I had cracked this, but I’ve discovered a bug. What we actually want is alphabetical listing of navons (rendered as hyperlinks to their landing pages) within each folder. To do that with a JCR-170 query, I came up with this:

SELECT rx:sys_contentid, rx:sys_contentstartdate 
FROM rx:rffNavon 
WHERE jcr:path LIKE '//Sites/External/PSD%' 
AND NOT jcr:path LIKE '//Sites/External/PSD/%/%/%' 
ORDER BY rx:displaytitle

That works fine, usually. The first condition in the WHERE clause finds navons in sub-folders of the specified folder, and the second condition filters out navons in sub-folders of those sub-folders (i.e. sub-sub-folders.) In other words, the above query finds navons, and lists them alphabatically, one level in the web site hierarchy at time.

But when I try it with a folder that contains sub-folders, but no sub-sub-folders (or at least none that have navons in them) it fails with an “unexpected exception” which then breaks any page that contains an autoslot that uses the query. Seemingly, you cannot search for NOT something if there are no items for it NOT to find! The following error message is displayed when testing this in the Rhythmyx Query Debugger:

org.hibernate.hql.ast.QuerySyntaxException: unexpected token: ) near line 1, column 543 [select new map(c0.id.sys_contentid as rx¨sys_contentid, cs.m_contentStartDate as rx¨sys_contentstartdate, c0.displaytitle as rx¨displaytitle, c0.id.sys_revision as rx¨sys_revision, f.owner_id as sys_folderid) from com.percussion.cms.objectstore.PSComponentSummary as cs left outer join cs.parentFolders as f,com.percussion.services.generated.RffNavon as c0 where cs.m_contentId = c0.id.sys_contentid and cs.m_contentTypeId = 314 and c0.id.sys_revision = cs.m_currRevision and (f.owner_id in (314,346,348,349,362,317,315,316,345,347,350) AND ) order by c0.displaytitle asc]

I’m not hugely confident that this can be fixed if I report it to technical support. So I guess I am back to ask if anyone can think of an alternative way to trick Rhythmyx into allowing us to do an automatic site map listed alphabetically. Something like the following…

About Us
	Contact Us
	History
	Mission Statement
News
	2006
	2007
	2008
Science
	Biology
	Chemistry
	Physics

… even if those sections and subsections are listed in a different order in the main navigation bars on the web site.

Andrew.

I’ve found my own solution to this, although it is hardly what you’d call elegant:

SELECT jcr:path, rx:sys_contentid, rx:sys_contentstartdate 
FROM rx:rffNavon 
WHERE jcr:path LIKE '//Sites/External/PSD%' 
AND NOT (jcr:path LIKE '//Sites/External/PSD/%/%/%' 
OR rx:sys_contentid = 0)
ORDER BY rx:displaytitle

The extra condition, rx:sys_contentid = 0, never matches anything, but it allows the other condition in the brackets to work.

Andrew.

I can scrap this dodgy code, seeing as I now have a method for sorting arrays of complex objects such those returned by the sys_ManagedNavContentFinder content finder in Velocity templates.

Here’s my code, adapt as required (e.g. to handle navons without assigned landing pages differently):


#set($arrayofmaps = [0])##
$arrayofmaps.clear()##
#foreach ($navon in $nav.root.getNodes("nav:submenu"))##
	#set($url = $navon.getProperty("nav:url").String)##
	#if($url)##
		#if($url != "#")##
			#set($map4navon = $rx.string.stringToMap("qwerty=uiop"))##
			$map4navon.clear()##
			#set($map4navon.title = $navon.getProperty("rx:displaytitle").String)##
			#set($map4navon.url = $url)##
			#if($arrayofmaps.add($map4navon)) #end##
		#end##
	#end##
#end##
#foreach( $map4navon in $tools.sorter.sort($arrayofmaps, "title"))##
	<li><a href="$map4navon.url">$map4navon.title</a></li>##
#end##