Umbraco: Ultimate Picker XSLT Example
Chatting with Dan (my partner-in-code at Bodenko) about the Ultimate Picker data-type in Umbraco, we realised that we couldn’t find any examples of how to use the data in XSLT. So obviously needing an excuse to write-up a new blog post, here we go.
If you need a quick overview about the Ultimate Picker data-type, see Tim Geyssens’ blog post.
For my example, using a default Umbraco install (with Runway), we will create a new data-type using the Ultimate Picker, (let’s call it “Runway Textpage Picker“), we select the ‘Database datatype‘ to be “Nvarchar”; the ‘Type‘ as a “List Box”; The ‘Parent nodeid‘ is “1048” and the ‘Document Alias‘ filter is “RunwayTextpage” – we also tick the ‘Show grandchildren‘ checkbox.
Next, we will assign the new “Runway Textpage Picker” data-type to a property of the Runway Textpage, we will call it “Related Content“. For more information about working with document types, please refer to the our.umbraco.org wiki page, (Working with document types).
Once the document-type is saved, we move on to the ‘Content‘ section. Select any of the Runway Textpages. You should now see the ‘Related Content‘ property panel, containing a list of all the other Runway Textpages. To select multiple items, hold-down the CTRL (or Command on the Mac) button. When you have finished, click the ‘Save and publish‘ button.
For the next part we get to the real meat of this blog post… the XSLT!
Create a new XSLT called “RelatedContent” (without the .xslt extension), keep it ‘Clean’ and tick the ‘Create Macro‘ checkbox. Next a quick short-cut for you; copy-n-paste the following XSLT into the main editor window.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxml="urn:schemas-microsoft-com:xslt" xmlns:umbraco.library="urn:umbraco.library" exclude-result-prefixes="msxml umbraco.library"> <xsl:output method="xml" omit-xml-declaration="yes"/> <xsl:param name="currentPage"/> <xsl:template match="/"> <xsl:variable name="preNodes"> <xsl:variable name="relatedContent" select="$currentPage/data[@alias='RelatedContent']" /> <xsl:variable name="nodeIds" select="umbraco.library:Split($relatedContent, ',')" /> <xsl:for-each select="$nodeIds/value"> <xsl:copy-of select="umbraco.library:GetXmlNodeById(.)"/> </xsl:for-each> </xsl:variable> <xsl:variable name="nodes" select="msxml:node-set($preNodes)/node" /> <xsl:if test="count($nodes) > 0"> <div class="related-content"> <h3>Related Content</h3> <ul> <xsl:for-each select="$nodes"> <li> <a href="{umbraco.library:NiceUrl(@id)}"> <xsl:value-of select="@nodeName" /> </a></li> </xsl:for-each></ul> </div> </xsl:if> </xsl:template> </xsl:stylesheet>
Here’s a quick explanation of what is happening in the XSLT. We are provided with a list of comma-separated nodeIds from the Ultimate Picker, which we need to parse/split – then pull back the XML node data, then we can transform it however we like!
The way we do this is 2-tiered, first we must loop through the comma-separated list, pulling back the XML node for each nodeId, adding it to an XSLT variable. Doing this will cause the XSLT variable to be a fragmented node-tree, which means that we need to convert the node-tree fragment into a node-set. (*Note: there are a gazillion ways to skin a cat – suggestions are welcome – this method works for me).
Once we have the complete XML node-set, we can transform into whatever HTML we like.
Now that we are done with the XSLT, we can edit our template in the ‘Settings‘ section. Select the “Runway Textpage” template. Somewhere after the ‘bodyText‘ property item, click on the ‘Insert Macro’ button. From the ‘Choose a macro‘ drop-down, select the ‘Related Content‘ option – this will add the macro code to the template.
Save the template and view the front-end page. We can now see the Related Content pages. Tada!