14

We've been discussing how to build navigation that is inline with the content that is published from SDL Tridion.

We typically see two approaches:

1) An xml page is published from sdl tridion that contains a list of the published content.

The main advantages are:

  • Users can publish content and view live before it appears within the website

  • The XML file is baked, the presentation server only has to read and parse the content

Dis-advantage: - The user has an extra task to do when new content is published / unpublished (If a user removes a page, they need to be aware that the navigation should be republished- this could be quite serious)

2) A dynamic approach - Using the Content Delivery API to pull the page links from the broker database.

The main advantages are: + Navigation is built based on only the published content

The dis-advantages are:

  • Performance overhead in pulling content from broker database for multiple items/queries

  • additional code required to cache the file in the delivery website.

I'm thinking of writing a deployer extension that automatically updates an XML file on the presentation server and automatically removes it on un-publish. The implementation could be configurable specify the path of the xml file (in the site or shared location) and which publications make use of this type of navigation xml.

There may be I/O issues I need to take into account when updating the file, but I wanted to run the high-level idea though the experts here as I'm sure there's some points that i'm not considering. For example: is deployer-extension supported in this sense? (I see a lot of functionality is decorated as deprecated)

Any thoughts and comments would be greatly appreciated.

12

I think there are as many navigation solutions as there are Tridion implementers :)

My favorite approach (which is usually tweaked to match any customer-specific requirements):

  • Use Structure Groups for hierarchy
  • Have a way to identify that a given page is the "index" page for an SG
  • Have a way to identify that a page or Structure Group should show in navigation
  • Publish the structure as (tree) xml. Typically you'll only need to publish this file when pages are published for the first time to a target, and can be easily handled in a Custom Resolver
  • Use an XSLT on the delivery side to transform this into a <ul><li> for the page

Identifying that a page is the index page can be done by checking the page file name ("index" or "default" or "whatever"), and identifying if the page/SG should be in navigation I tend to do with the "000 name" convention. This doubles as giving me an ordering attribute as well. If page or SG starts with numbers (RegexPattern = @"^[\d]* ";) then it should be in navigation.

I then use a page template + page to publish this as an XML list to the delivery side. Will not paste code in here for this, as my current "standard" navigation template is 300+ lines (I also tend to include page/SG metadata as attributes in the XML and some other "magic" stuff).

On the delivery side, the page currently being shown needs to load the navigation as follows:

<c:import var="navigationXml" url="/system/navigation.xml" />
<c:import var="navigationXsl" url="/system/nav.xslt" />
<x:transform doc="${navigationXml}" xslt="${navigationXsl}" >
  <x:param name="pageUri">tcm:28-2806-64</x:param>
  <x:param name="publicationUri">tcm:0-28-1</x:param>
</x:transform>

c and x in the above code refers to the following taglibs:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>

I disagree with your statement:

If a user removes a page, they need to be aware that the navigation should be republished- this could be quite serious)

This won't be an issue at all if you use Dynamic Linking for your navigation. In my preferred approach, I use a template like this in the XSLT:

<xsl:template name="PageLink">
  <xsl:param name="linkText" />
  <xsl:param name="target" />
  <xsl:param name="publicationUri" />
  <xsl:variable name="pagelinkFactory" select="java:com.tridion.linking.PageLink.new($publicationUri)" />
  <xsl:variable name="pagelink" select="java:getLink($pagelinkFactory, $target)" />
  <xsl:choose>
    <xsl:when test="java:isResolved($pagelink)">
      <li>
        <xsl:element name="a">
          <xsl:variable name="url" select="java:getURL($pagelink)" />
          <xsl:attribute name="href">
            <xsl:value-of select="$url" />
          </xsl:attribute>
          <xsl:value-of select="$linkText"/>
        </xsl:element>
      </li>
    </xsl:when>
    <xsl:otherwise>
      <!-- You may want to remove this comment from your production servers -->
      <!-- Leave it in DEV and QA to assist tracking page link resolving -->
      <xsl:comment>Link to page <xsl:value-of select="$target"/> was not resolved</xsl:comment>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

You can do a similar approach in .NET using an extension object for the linking part.

When using a solution like this only pages that are currently published will show in the navigation, and when coupled with cache the impact is minimal.

  • Thanks nuno. that xslt is a great bit of code. I wasn't aware it was possible to do something like <xsl:variable name="pagelinkFactory" select="java:com.tridion.linking.PageLink.new($publicationUri)" /> - genius stuff! – johnwinter Feb 21 '13 at 16:19
  • Sorry if I'm being thick here but what decides which pages to show in the navigation in the first place? E.g. what list are we appying this template to? For example: in the XML file approach, for Structure Groups you can set properties like "show_in_left_hand_nav" and in the keyword based XML approach you use the keyword hierarchy. Is this for a situation where all pages are in the nav? – Rob Stevenson-Leggett Feb 21 '13 at 16:25
  • True, I missed part of the equation and focused on the delivery. Will add to my answer – Nuno Linhares Feb 21 '13 at 16:29
  • In a lot of the tridion forums and discussions navigation as XML has been a performance issue for larger government sites but this solution seems to solve that – indiejonesjunior Feb 25 '13 at 0:23
  • Publishing the XML used to be a big performance hog - I remember 5-10 minutes delays to render the navigation on medium-sized sites (20K pages)... but this seems to be a lot faster from T2011 (am I the only one to think this?) – Nuno Linhares Feb 25 '13 at 1:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.