Wednesday, March 5, 2008

Navigation Elements

The design of your content tree can dramatically impact the ease of implementing navigation elements such as hierarchical navigation or breadcrumbs.

When the content tree mirrors the information architecture of your web site, generating hierarchical navigation is extremely simple. An XSL code snippet could be as straightforward as the following:

  <xsl:for-each select="$home/item[@template='section']">
    <div>
      <sc:link>
        <sc:text field="menu title" />
      </sc:link>
    </div>
  </xsl:for-each>

In this simple example, the XSLT loops through the children of the home item and outputs a link to each child that is based on the Section template. The simplicity of this rendering is dependent upon the mirroring of the content tree and the information architecture of the site. When possible, this is a very desirable way to design the content hierarchy due to the development productivities that can be realized.

Depending upon what should appear in the site navigation, however, this exact mirroring may not be possible. Business users may want to control the items listed in the navigation based on editorial decisions rather than a static information architecture. Consider a requirement for the following items to appear in the navigation: Specials, CEO Blog, Products and About Us. These items, however, may be scattered throughout the content tree:

I. Home
  a. Products
    i. Specials
    ii. Product A
  b. About Us
    i. CEO Blog

There is no simple logic to determine which items will appear in the navigation and – even if there were – this logic may change over time. To address this, developers may wish to allow business users to configure the navigation themselves. One way to accomplish this requires that the navigation is described in metadata items, possibly in the /sitecore/content/global folder.

I. Content
  a. Global
    i. Navigation
      1. Nav 1
      2. Nav 2
      3. Nav 3
      4. Nav 4

Each of the Nav elements in the above example is based on a template with a Navigation Item field. This field may be a tree list control that allows business users to select an arbitrary item from the content tree. Business users may sort the children of /content/global/navigation in the order they should appear in the navigation. A simple rendering would be:

  <xsl:for-each select="/*/item[@key='content']/item[@key='global']/item[@key='navigation']/item">
    <div>
      <xsl:variable name="sourceItem" select="sc:item(sc:fld('navigation item', .), .)" />
      <sc:link select="$sourceItem">
        <sc:text field="menu title" select="$sourceItem" />
      </sc:link>
    </div>
  </xsl:for-each>

A perhaps simpler approach (though more complex in XSL) would be to implement a single Navigation item:
I. Content
  a. Global
    i. Navigation

The Navigation item would have a field called “Menu Items” of type treelist whose source is the /sitecore/content/home item. Business users can choose which items they want to appear in the navigation and sort them based on editorial decisions.

Yet another way to tackle this problem would be to create a base template for your site with a “Show in Navigation” field. Your rendering logic could perform a descendants query starting with the home item to check for the value of the field. While the solution is simple, this query could create extreme overhead problems as descendants queries can be very expensive.

Rendering breadcrumbs poses similar challenges to those described with hierarchical navigation. When the page navigation mirrors the content tree, rendering breadcrumbs is trivial from a coding perspective:

  <xsl:for-each select="ancestor::item">
    <xsl:if test="position() > 2">
      <sc:link>
        <sc:text field="menu title" />
      </sc:link> >
    </xsl:if>
  </xsl:for-each>
  <sc:text field="menu title" />

If the user has navigated to the /sitecore/content/Home/Products item, the above rendering will output: Home > Products.

When the content tree does not mirror the information architecture of the website, breadcrumbs become more complicated. Imagine the following content hierarchy:

I. Home
  a. News
    i. 2007
      1. January
      2. February
        a. 01
          i. News Story 1
          ii. News Story 2

In the example above, News Stories are structured by the year, month and date they are entered. However, business requirements may dictate that the breadcrumb exclude the year, month and date items and display all News Stories as children of the News section. For example, the breadcrumb for News Story 1 should be: Home > News > News Story 1. To implement this, a simple filtering of content items by template may be sufficient:

  <xsl:for-each select="ancestor::item">
    <xsl:if test="position() > 2 and @template != 'folder'">
      <sc:link>
        <sc:text field="menu title" />
      </sc:link> >
    </xsl:if>
  </xsl:for-each>
  <sc:text field="menu title" />

The more your content tree deviates from your site’s information architecture, the more complex your rendering logic will need to be and the more reliant your renderings will be on metadata. This should not imply that your content tree needs to be determined by ease-of-coding considerations. However, where developer productivities can be achieved by simplifying content organization, this should be considered.

4 comments:

Zinavo Tech said...

Thanks for such a wonderful explanations,good post.
Website Design Companies | Web Design Companies Bangalore

bubblefootball said...

Thanks for sharing this great post on content management,..
Decoupled CMS

Xantatech said...

Nice Blog!!
Xantatech offers solutions for Web Content Management System all challenges concerned to content management, including document management, digital asset management, records management, web content management and enterprise content integration.

Event Stories said...


Great Simple and Elegant Wishes from Best Event Management Companies in Kochi City Thank You for Listening