localLinks

20 October 2009 by Administrator

{localLinks}

Overview

On a recent project we stumbled into an interesting problem. We had been asked to build a very simple website, however we wanted to allow the site to grow and develop so making it as flexible as possible was paramount. The site would have monthly publications which could contain 'assets'. It was likely the 'assets' would be used in future publications so we wanted to store these in their own folder.

The publication would show a preview of the asset & when it was clicked the asset would play at the top of the publication. This was done by passing the nodeID of the asset into the querystring of the publication page. The publication also showed a teaser which was associated to the asset.

This gave our client a very flexible solution. However our clients wanted to be able to link to other assets within the teaser (contentTeaser) field.

This presented us with a problem, the content editor could link to other assets. But when this link was parsed it would link to the other document. This was not the behavior we wanted, we wanted to access the nodeID and pass this in the query string to keep behavior uniform.

-

To do this we needed to interupt how Umbraco parsed the XML by Encoding the 'contentTeaser', accessing the link information, replacing it, and then decoding the data so it would be suitable for front-end render again.

We did this using XSLT, eXSLT, Regex and some C#.

References

our.Umbraco.org - Extend your XSLT with Custom Functions
eXSLT.org - Regex Replace
eXSLT.org - Regex Match (more useful examples)
our.Umbraco.org - Umbraco Library

 

The Code

This document has been broken down into six sections, at the bottom of this page is a link to download the XSLT.

  1. Custom XSLT Function
  2. Get the $currentPage URL
  3. Get the $currentPage Content and Encode (variable)
  4. Set the Regex String Replacement
  5. Run Regex Replace
  6. Get the Replace Output, Decode & Display.

 

 

1. Custom XSLT

This code has been referenced from the Umbraco Wiki you can find it here.

<msxml:script implements-prefix="htmlDecode" language="C#">
<msxml:assembly name="System.Web"/>
<msxml:using namespace="System.Web"/>

<![CDATA[ public string convertText(string text) { string decodedStr = HttpUtility.HtmlDecode(text); return decodedStr; } ]]>

</msxml:script>

 

2. Get the $currentPage URL

We need the URL for the page we want to make the links reference too.
Using the 'umbraco.library:NiceURL(string)' function.

This URL is assigned the variable '$niceURL'.

<xsl:variable name="niceURL">
<xsl:value-of select="umbraco.library:NiceUrl($currentPage/@id)"/>
</xsl:variable>


3. Get the $currentPage Content and Encode (variable)

Next we grab the content which contains our links. In this case the datatype was a richtext editor. To be able to process this with the eXSLT:Regex extension we needed to encode the characters in the HTML.

This is really easy to do using the 'umbraco:library:HtmlEncode(string)' function.

<xsl:variable name="assetTeaser">
<xsl:value-of select="umbraco.library:HtmlEncode(data [@alias = 'assetTeaser'])"/> </xsl:variable>


4. Set the Regex String Replacement

For some reason I couldn't write the whole replacement string in the regex replace function. So I pull in the string I wanted by setting it as a variable. In anyone knows how to fix this please let me know!

<xsl:variable name="niceURLregex">
..<xsl:value-of select="$niceURL"/>
?clip=$1
</xsl:variable>


5. Run Regex Replace

Using a eXSLT function called replace would can feed in our content, find the {localLinks} and then replace these with the variable we set earlier.

in this case, we are looking for localLink and a 4 digit number. Its worth noting the number could be longer than four digits if your site has many nodes. We also inform the processor that it is dealing with a multiline input (m), a ungreedy pattern (U) and to treat each string as a single line (s); giving us 'mUs'.

We now need to feed the function the replacement information. As noted above I could not find a way to write what is stored in the variable directly. Because of this we simply pull the variable in.

 

This string tells is to;

  • .. - move to the root.
  • $niceURL - get the niceURL variable, defined in the top of the document. This is just the URL for the current page.
  • ?clip= - add some static text
  • $1 - add the string, e.g "1234" in /{localLink:(1234)}

<xsl:variable name="assetTeaserReplace">
<xsl:value-of select="Exslt.ExsltRegularExpressions:replace($assetTeaser, '/{localLink:([0-9][0-9][0-9][0-9])}', 'mUs', $niceURLregex )" disable-output-escaping="no" /> </xsl:variable>


6. Get Replace Output, Decode and Display

Okay so we've taken $assetTeaser, and using some regex we've updated the links. Now we need to Decode it. (we encoded it to start with). Its at this point we run the custom function we set at the top of the document which gives us the capability to decodeHTML.

<xsl:value-of select="htmlDecode:convertText(string($assetTeaserReplace))" disable-output-escaping="yes" />

-

You can download the XSLT for this here.