Random images in Umbraco
Following on from a recent post of mine about how to setup changeable headers using the media picker in Umbraco a new site I have been working on required something a little extra -they wanted the headers to simply be chosen at random. from a given media folder.
First, create a new (blank) XSLT file and add the following:
Random header images XSLT
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE xsl:Stylesheet [ <!ENTITY nbsp " "> ]>
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"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:math="urn:schemas-hizi-nl:math"
xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings"
xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath"
exclude-result-prefixes="msxml Exslt.ExsltMath Exslt.ExsltStrings math umbraco.library">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<msxml:script language="JavaScript" implements-prefix="math">
function random(numDie,numMax,numMin){
if (numMin==null){numMin=1;}
var sum=0;
for (var index=0;index<numDie;index++){
sum+=Math.floor(Math.random()*(numMax-numMin) + numMin);
}
return "" + sum;
}
function floorme(numFloor){
return "" + Math.floor(numFloor);
}
</msxml:script>
<xsl:variable name="StartNode" select="/macro/StartNode/node/@id" />
<xsl:variable name="parent" select="umbraco.library:GetMedia($StartNode, 'false')" />
<xsl:variable name="random" select="math:random(1, count($parent/node)+1, 1)"/>
<xsl:template match="/">
<xsl:for-each select="$parent/node">
<xsl:if test="position()=$random">
<xsl:if test="./data [@alias = 'umbracoExtension'] = 'gif' or ./data [@alias = 'umbracoExtension'] = 'jpg' or ./data [@alias = 'umbracoExtension'] = 'jpeg' or ./data [@alias = 'umbracoExtension'] = 'png'">
<style type="text/css">
#header{
background-image: url(<xsl:value-of select="./data [@alias = 'umbracoFile']"/>);
}
</style>
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
What this does is it uses the StartNode (a media folder) passed in from the macro to loop through any valid files (in this case jpg/gif/png and pull out the image if it's valid. I was thinking about replacing the for-each loop and simply using the index but I'm not sure if there would be any performance improvement except for if there were a lot of header images in the folder.
You'll then need to create a new macro and add a parameter with the name "StartNode" and select "mediaCurrent" as the Type. That's it :)
I'd like to build on this and have a "valid" headers selector which would use a Multiple Media picker and would allow for banner ads to be selected at random but that can wait for a client that needs it ;)