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.
Intersting stuff mike…I don’t understand any of it. maybe you should add a music section :)
mko
Thanks for stopping by, Mike. I’ll work on some content for non-geek types.