Skip to content

Instantly share code, notes, and snippets.

@greystate
Last active September 25, 2015 10:18
Show Gist options
  • Select an option

  • Save greystate/906495 to your computer and use it in GitHub Desktop.

Select an option

Save greystate/906495 to your computer and use it in GitHub Desktop.
Code listings for "Using the Multi-Node Tree Picker in XSLT" (Pimp My XSLT article)
<!-- Link -->
<p class="goodness">
<a href="http://4815162342x.com/numbers" title="This is very mysterious…">
Today’s Mystery Link — Make sure you’re ready!
</a>
</p>
<!-- Video -->
<video class="sublime" width="400" height="300" poster="pimpcast.png" preload="none">
<source src="TextMate-XSLT.mp4" />
<source src="TextMate-XSLT.m4v" />
<source src="TextMate-XSLT.ogv" />
</video>
<!-- Blogpost -->
<section>
<header>
<h1>The Numbers Are Bad!</h1>
<time datetime="2011-03-19T00:21:28+0100">Yesterday</time>
</header>
<p>
Today was awesome — guess what? I lost my phone number
and this cool racoon came out of the blue!
</p>
</section>
<Link id="1288" nodeName="Numbers link" isDoc="">
<linkText>Today&#8217;s Mystery Link &#8212; Make sure you&#8217;re ready!</linkText>
<linkURL>http://4815162342x.com/numbers</linkURL>
<linkTitle>This is very mysterious&#8230;</linkTitle>
</Link>
<Video id="1294" nodeName="TextMate XSLT Demo" isDoc="">
<posterImage>1057</posterImage>
<sources>1771</sources>
</Video>
<BlogPost id="1301" nodeName="The Numbers Are Bad!" isDoc="">
<postDate>2011-03-19T00:21:28+0100</postDate>
<bodyText>
<html>
<p>
Today was awesome — guess what? I lost my phone number
and this cool raccoon came out of the blue!
</p>
</html>
</bodyText>
<umbracoUrlName>numbers</umbracoUrlName>
</BlogPost>
<StreamPage id="2812" nodeName="Stream of Stuff" isDoc="">
<streamContent>
<MultiNodePicker>
<nodeId>1288</nodeId>
<nodeId>1294</nodeId>
<nodeId>1301</nodeId>
</MultiNodePicker>
</streamContent>
</StreamPage>
<!-- Template for a BlogPost -->
<xsl:template match="BlogPost">
<section>
<header>
<h1><xsl:value-of select="@nodeName" /></h1>
<time datetime="{postDate}">
<!-- Handle the custom formatting elsewhere -->
<xsl:apply-templates select="postDate" mode="date" />
</time>
</header>
<!-- Handle the Markdown Editor XML output -->
<xsl:apply-templates select="bodyText" />
</section>
</xsl:template>
<!-- Template for Link -->
<xsl:template match="Link">
<p class="goodness">
<a href="{linkURL}" title="{linkTitle}">
<xsl:value-of select="linkText" />
</a>
</p>
</xsl:template>
<!-- Template for a Video -->
<xsl:template match="Video">
<video class="sublime" preload="none">
<!-- Create width, height and poster attributes from posterImage -->
<xsl:apply-templates select="posterImage" mode="media.attributes" />
<xsl:apply-templates select="sources" mode="media" />
</video>
</xsl:template>
<xsl:template match="/">
<xsl:for-each select="$currentPage/streamContent/MultiNodePicker/nodeId">
<xsl:variable name="node" select="umb:GetXmlNodeById(.)" />
<!-- Handle the kind of node we got back -->
<xsl:apply-templates select="$node" />
</xsl:for-each>
</xsl:template>
<xsl:key name="document-by-id" match="*[@isDoc]" use="@id" />
<xsl:template match="/">
<xsl:apply-templates select="$currentPage/streamContent/MultiNodePicker/nodeId" />
</xsl:template>
<xsl:template match="nodeId">
<!-- Handle the node with this id -->
<xsl:apply-templates select="key('document-by-id', .)" />
</xsl:template>
<xsl:key name="document-by-id" match="*[@isDoc]" use="@id" />
<xsl:template match="/">
<xsl:apply-templates select="$currentPage/streamContent" mode="multipicker" />
</xsl:template>
<xsl:template match="MultiNodePicker" mode="multipicker">
<!-- Handle all the nodeIds in one go (!) -->
<xsl:apply-templates select="key('document-by-id', nodeId)" />
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="$currentPage/streamContent" mode="multipicker" />
</xsl:template>
<!-- Templates for the various Document Types here... -->
<xsl:include href="_MultiPickerHelper.xslt" />
<xsl:key name="document-by-id" match="*[@isDoc]" use="@id" />
<xsl:template match="MultiNodePicker" mode="multipicker">
<!-- Grab all the selected nodes using the key -->
<xsl:variable name="nodes" select="key($key, nodeId)" />
<!-- We need a reference back to the nodeId elements, so collect them -->
<xsl:variable name="nodeIds" select="nodeId" />
<!-- We can't use position like this: $nodeIds[. current()/@id]/position(),
so instead count the number of preceding siblings -->
<xsl:apply-templates select="$nodes">
<xsl:sort
select="count($nodeIds[. = current()/@id]/preceding-sibling::nodeId)"
data-type="number" order="ascending"
/>
</xsl:apply-templates>
</xsl:template>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment