Recursive select of URL Picker nodes in XSLT based on a macro parameter string.
I figured out how to recursive select URL Picker Nodes a while back but now I need to specify in my macro a parameter which tells the macro which page property is the correct URL Picker to parse. Here is the hard coded macro that works:
<xsl:param name="currentPage"/>
<xsl:template match="/">
<!-- Process the first ancestor (or self) that has a value in bottomRightBrandURL -->
<xsl:apply-templates select="$currentPage/ancestor-or-self::*[normalize-space(bottomRightBrandURL/url-picker/url)][1]/bottomRightBrandURL" />
</xsl:template>
<!-- Template for the bottomRightBrandURL -->
<xsl:template match="bottomRightBrandURL">
<a href="/">
<xsl:attribute name="href"><xsl:value-of select="parent::*/bottomRightBrandTargetURL"/></xsl:attribute>
<xsl:attribute name="style">background:transparent url('<xsl:value-of select="url-picker/url"/>') no-repeat center;</xsl:attribute>Home</a>
</xsl:template>
</xsl:stylesheet>
Now imagine that I have 2,3 or 4 url pickers on my page "bottomRightBrandURL" and "bottomLeftBrandURL" and ... Rather than making a macro for each, I want to pass these Page Property aliases into my macro and use the macro property where "bottomRightBrandURL" occurs. Notice that in the bottomRightBrandURL template the node I need to select is acctually bottomRightBrandTargetURL.
You can use the name() function to solve this puzzle - just sure to follow your convention of naming the TargetURL properties with the same prefix as the BrandURL properties:
<xsl:template match="/">
<xsl:variable name="prop" select="/macro/property" />
<xsl:apply-templates select="$currentPage/ancestor-or-self::*[normalize-space(*[name() = $prop]/url-picker/url)][1]/*[name() = $prop]" />
</xsl:template>
<!-- Template for the xxxBrandURL properties -->
<xsl:template match="bottomRightBrandURL | bottomLeftBrandURL | MORE_NAMES_HERE">
<!-- Take value of like-named TargetURL sibling property -->
<a
href="{../*[substring-before(name(), 'TargetURL') = substring-before(name(current()), 'TargetURL')]}"
style="background:transparent url('{url-picker/url}') no-repeat center;"
>
<xsl:text>Home</xsl:text>
</a>
</xsl:template>
Thanks for the quick repy! Is there any way to pass the the value of $prop into the template match rather than creating an ever expanding OR statement? I was hoping to make this a more generic utility for dealing with the structure of the url picker.
Interesting... I was so close to getting the [name()=$prop] on my own but I kept getting an error on "[". The solution you have presented adds *[name()=$prop] what exactly is the * in this context and why is it needed?
You need the asterisk because the thing you put in the square brackets (it's called a "predicate") is only a filter for the previous "location step", which needs to select some actual nodes. So for example:
<!-- Select all NewsItem children -->
$currentPage/NewsItem
<!-- Select all NewsItem children where the archived property is 1 -->
$currentPage/NewsItem[archived = 1]
<!-- Select all childnodes (in Umbraco this means documents AND their properties!) -->
$currentPage/*
<!-- Select only document children (i.e. "pages") -->
$currentPage/*[@isDoc]
etc...
So the asterisk is a wildcard for actual XML elements, regardless of their name.
And you need the wildcard before the filter because you need some nodes to apply the filter to.
Recursive select of URL Picker nodes in XSLT based on a macro parameter string.
I figured out how to recursive select URL Picker Nodes a while back but now I need to specify in my macro a parameter which tells the macro which page property is the correct URL Picker to parse. Here is the hard coded macro that works:
Now imagine that I have 2,3 or 4 url pickers on my page "bottomRightBrandURL" and "bottomLeftBrandURL" and ... Rather than making a macro for each, I want to pass these Page Property aliases into my macro and use the macro property where "bottomRightBrandURL" occurs. Notice that in the bottomRightBrandURL template the node I need to select is acctually bottomRightBrandTargetURL.
Thanks in advance!
Hi cchehn,
You can use the name() function to solve this puzzle - just sure to follow your convention of naming the TargetURL properties with the same prefix as the BrandURL properties:
Hopefully it works for you!
/Chriztian
Chriztian,
Thanks for the quick repy! Is there any way to pass the the value of $prop into the template match rather than creating an ever expanding OR statement? I was hoping to make this a more generic utility for dealing with the structure of the url picker.
-C.
Hi cchehn,
There's usually always a solution - in this case you could use an asterisk instead:
/Chriztian
Chriztian,
Interesting... I was so close to getting the [name()=$prop] on my own but I kept getting an error on "[". The solution you have presented adds *[name()=$prop] what exactly is the * in this context and why is it needed?
Thanks,
-C.
Hi,
You need the asterisk because the thing you put in the square brackets (it's called a "predicate") is only a filter for the previous "location step", which needs to select some actual nodes. So for example:
So the asterisk is a wildcard for actual XML elements, regardless of their name.
And you need the wildcard before the filter because you need some nodes to apply the filter to.
Hope that helps :-)
/Chriztian
Yes that does help! What a wonderful explanation. Thanks very much.
-C.
is working on a reply...