Site Studio Recipes:Easy idoc breadcrumbs with ssNavNodeList

The under-documented ssNavNodeList is a result set baked in to all Site Studio pages. While it shows up in at least one sample fragment, there’s no mention of this handy little tool in the documentation. I was forever recreating something similar using loops and some flavor of GET_RELATIVE_NODE_ID, until I stumbled on ssNavNodeList and a better way.

ssNavNodeList provides a list of nodeId’s representing the site hierarchy from home page down to the current page — its single column is simply named ‘nodeId.’ So, if the current page fits in the site like so:

  - Home (101)
    - AncestorPage (111)
      - ParentPage (119)
        - CurrentPage (175)

ssNavNodeList for CurrentPage would contain “101,111,119,175.”

This makes creating Idoc script based breadcrumbs a piece of bread cake. Give the same site structure, we want to produce something like:

Home » AncestorPage » ParentPage » CurrentPage

Here’s a simple version of my favorite recipe for doing just that:

The code

[!--$ thisNodeId = nodeId --]
 
<!-- create the crumb delimiter  -->
[!--$ delimiter=" » " --]
 
[!--$ loop ssNavNodeList --]
  <!-- grab the node label -->
  [!--$ nodeLabel = ssGetNodeProperty( nodeId, "label" ) --]
  [!--$ if not strEquals( nodeId, thisNodeId ) --]
      <!-- not the current node, so just write a link + delimiter -->
      <a href="ssNODELINK/[!--$ nodeId --]">
        [!--$ nodeLabel --]
      </a>[!--$ delimiter --]
  [!--$ else --]
      <!-- we've reached current node so check for primary/secondary layout -->
      [!--$ if isTrue( isSecondaryPage ) --]
        <!-- this is a secondary page, so use the dDocTitle of a contributed item -->
        <!-- first write the current nodeId's label as a link -->
        <a href="ssNODELINK/[!--$ nodeId --]">
          [!--$ nodeLabel --]
        </a>[!--$ delimiter --]
 
        <!-- get the dDocTitle for the contributed item and use it -->
        [!--$ dDocName = region1 --]
        [!--$ executeService("SS_DOC_INFO_LATEST") --]
        [!--$ myPageName = DOC_INFO.dDocTitle --]
        <em>[!--$ myPageName --]</em>
      [!--$ else --]
        <!-- primary page, so just write the current node label -->
        <em>[!--$ nodeLabel --]</em>
      [!--$ endif --]
    [!--$ endif --]
[!--$ endloop --]
 
<!-- / #crumb -->

The details

In a nutshell, as we loop over the ssNavNodeList, nodeId gets the value of a node in the list. We compare that to the current page’s nodeId that we saved in thisNodeId — as long as they’re not equal we’re dealing with an ‘ancestor’ page, and we just write a link followed by the delimiter.

<a href="ssNODELINK/[!--$ nodeId --]">[!--$ nodeLabel --]</a>[!--$ delimiter --]

When nodeId and thisNodeId do become equal, we’ve reached the current node. At this point we want to determine whether we’re on a primary or secondary layout. If it’s a primary page (lines 26-28), we can just spit out the node label and we’re done. If it’s a secondary page, though,

[!--$ if isTrue( isSecondaryPage ) --]

we’re likely dealing with dynamic content in a replaceable region and we might want to go a bit further to get an appropriate label.

Secondary pages

A typical implementation in my shop has secondary layouts displaying contributed content items in replaceable regions — we consistently use ‘region1′ as the identifier for these ‘main content’ regions. In these cases, we want to use the value of title (dDocTitle) in the content item’s metadata for the crumb label. That code, one more time, looks like:

<a href="ssNODELINK/[!--$ nodeId --]">[!--$ nodeLabel --]</a>[!--$ delimiter --]
 
<!-- get the dDocTitle for the contributed item and use it -->
[!--$ dDocName = region1 --]
[!--$ executeService("SS_DOC_INFO_LATEST") --]
[!--$ myPageName = DOC_INFO.dDocTitle --]
<em>[!--$ myPageName --]</em>

Here we’re first writing out the label for the current node as a link that would take us to the primary page for the section.

Next we assign the content ID stored in ‘region1′ to dDocName in preparation for getting the DOC_INFO for that item — the executeService call in line 23. Now we can grab the value of dDocTitle and display it as the last label in the crumb in lines 24 & 25.

Things what people said

01 Jan 212009
Jeffrey Smith

I was wondering if you had more resources than what is provided by Oracle, metalink.oracle.com, the Oracle forum, Stellent user group, and the one Stellent book in existence which was written using 7 not 10.1.

Our team has just started working on a large implementation of Stellent and are trying many customized applications of it.

Would love to chat with any other developers that use it and start building at least our own documentation of problems, solutions, and like you custom fixes to common problems.

02 Jun 232009
Luis

This is fantastic!!

The code is very clear and concise. Our company is doing a similar thing with the breadcrumb and I’ve been racking my brain to figure it out. This has saved me hours of development!

Thanks!

03 Jul 012009
justcaldwell

Thanks for stopping by Luis, I’m glad to hear the code helped.

04 Jul 202009
Mike

Wow … that is great, but what version are you using as I am on Stellent 7.1 … upgrading to 10gr3 in the fall.

Thanks

05 Jul 222009
justcaldwell

We’re currently on Content Server v7.5 and Site Studio v7.7.

I don’t know if ssNavNodeList is available in your version, but you can always append “?IsJava=1″ to the URL of one of your Site Studio sites and see if it shows up in the results.

Good luck.

speak your peace