BLOG - Filter: XSLT
Related Links in Umbraco
Freitag, 19. Juni 2009, Christoph Ertl

related_documents_buttonRelated links can be very useful to give the visitor an easy way to find additional information. This could be a page on your site or even a link to an external site.
How can this be realized with Umbraco?

A built in functionality is not available addressing this issue.

But there's already an extension package available. It's called Related Links. The package provides a property type allowing to add multiple internal and external links to a document.

I really feel confident with Umbraco and it's flexibility. Hence, I always think twice before installing a package.

Working with built in Features

With a few steps we can solve this issue using built in features and even get more flexibility.

Create a document type

To solve this we introduce a new document type called "Alias" with two properties "Node" and "Url". For easier editing we add a tab called "Settings" and assign the properties to this tab.

Properties of Alias Node

We want to add documents of this type to other documents. Therefore we must set the Alias document type as "Allowed child nodetype" of the document type where want the aliases to add to.

Set as allowed child node type

Create an xslt file with macro

To render the links we create an XSLT file ListAliases.xslt with the corresponding macro.
In this xslt stylesheet we iterate over all child nodes and set the href attribute according to the kind of link.

<xsl:for-each select="$currentPage/node [@nodeTypeAlias = 'alias']">
 
<
xsl:sort select="@sortOrder" order="ascending"/>
 
<
li><a>
   
<
xsl:attribute name="href">
     
<
xsl:choose
       
<
xsl:when 
         
test="string(./data [@alias = 'toUrl']) = ''"

         
<
xsl:value-of select="umbraco.library:NiceUrl(./data [@alias = 'toNode'])"/>
       
</
xsl:when>
       
<
xsl:otherwise>
         
<
xsl:value-of select="./data [@alias = 'toUrl']"/>
       
</
xsl:otherwise>
     
</
xsl:choose>
   
</
xsl:attribute>
   
<
xsl:value-of select="@nodeName"/>
 
</
a></li>
</
xsl:for-each>

Use the macro

The last step is to use the macro in the template where the related links should be displayed.

...
<h2>Related</h2>
<?UMBRACO_MACRO macroAlias="ListAliases" ></?UMBRACO_MACRO>

Working with the solution

Sample contentTo create related links we now just have to add a child node of type Alias to our document for each related link we need.

In this child nodes just set the Node or the url to link to.

In this example we have two related links - one external (Umbraco) and one internal (My Blog).

Settings of external link  Settings of internal link

The resulting page could look like the following

Rendered content

Key Benefits

  • First of all. A document type is the main feature of Umbraco and therefore this solution should work for all future releases and for all installations. See also CMS structure granularity - not only in Umbraco.
  • You can decide when to publish and when to remove the link by using the built in functionality available for all nodes.
  • This solution is very extensible. You could add additional properties to the Alias document type for instance:
    • an image to be displayed next to the link
    • a  flag for a special sort criteria
    • a description which is displayed with the tooltip of the link.
    • You could introduce a document type called "Alias group" for grouping the links in for instance "Related" and "Depends on".
    • You could even manage your links at the root of your content tree to reuse them at different nodes.

Sort Umbraco Nodes by sortOrder property
Donnerstag, 07. August 2008, Christoph Ertl

Today I added two nodes, changed the sorting and published the whole bunch. The first look at the resulting page was surprising because the sort order seemed to be totally confused.

After a while I realized that I reached the count of 11 nodes and the node with the sortOrder = 10 was displayed after the one with sortOrder = 1.

Got it? The property is compared as string.

The problem is that XSLT handles values as string unless you declare what type should be used.

So instead of sorting nodes with

<xsl:sort
  
select="@sortOrder"
  
order="ascending"
/>

you have to set the data-type to be used for comparison

<xsl:sort
  
select="@sortOrder"
  
order="ascending"
  
data-type="number"
/>

List categories of Umbraco blog
Sonntag, 18. Mai 2008, Christoph Ertl

I'm not sure if I deleted the xslt file or am just kind a blind. But I found nothing providing me a listing of all available categories and their count of occurrence. So here is my solution.

First of all we have to know the id of the data type used for the categories. Execute the following statement against the database and note the resulting dataTypeId.

SELECT dataTypeId FROM cmsPropertyType
WHERE alias =
'categories'

The resulting id (in my case: 1094) is used in the xslt macro to get all predefined values. The macro iterates over all predefined values of the dataType with the id 1094 and counts all nodes of type umbracoBlogPost containing this predefined value.

<xsl:for-each select="umbraco.library:GetPreValues(1094)/node()">
<
xsl:sort />
<
a>
  <
xsl:attribute name="href">
    <
xsl:text>/blog.aspx?filterBy=</xsl:text><xsl:value-of select="current()"/>
  </
xsl:attribute>
  <
xsl:value-of select="." />
</
a> (<xsl:value-of select="count($currentPage/ancestor-or-self::node/descendant-or-self::node [@nodeTypeAlias = 'umbracoBlogPost' and string(data [@alias='umbracoNaviHide']) != '1' and contains(./data [@alias='categories'], current())])" />)

  <br/>

</xsl:for-each>

To get the macro work properly you have to use the id of the dataType as described above and correct the url to point to the page supporting the filterBy parameter.