Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • tesuji 95 posts 139 karma points
    Mar 01, 2010 @ 23:32
    tesuji
    0

    Random quotes, images

    My client wants to include random images and quotes on a web page. I need to pick randomly from a collection of existing images and quotes. (It doesn't have to be exactly random, but something similar - to be different with a new page load). 

    Does Umbraco do this already, or are there sample code or packages I can use? 

    I think .NET has an ad rotator control. Would it be easiest to just put this in a user control?

  • Jesper Hauge 298 posts 487 karma points c-trib
    Mar 01, 2010 @ 23:57
    Jesper Hauge
    0

    If you're doing this from a usercontrol - you can create an extension method to the umbraco.presentation.nodeFactory.Node class, that selects a random child node like this:

    using System;
    using umbraco.presentation.nodeFactory;
    
    namespace My.Umbraco.Extensions
    {
      public static class UmbracoExt
      {
        /// <summary>
        /// Returns a random childnode from provided node
        /// </summary>
        /// <param name="node">node to look in</param>
        /// <returns>Node</returns>
        public static Node GetRandomChild(this Node node)
        {
          if (node.Children.Count == 0)
            return null;
          if (node.Children.Count == 1)
            return node.Children[0];
          var rnd = new Random(DateTime.Now.Millisecond);
          return node.Children[rnd.Next(0, node.Children.Count)];
        }
      }
    }

    This enables getting a random child node and its data like this in the codebehind:

    using System;
    using System.Web;
    using System.Web.UI;
    using My.Umbraco.Extensions;
    using umbraco;
    using umbraco.BusinessLogic;
    using umbraco.presentation.nodeFactory;
    
    namespace petersen_gruppen.dk.usercontrols
    {
        public partial class TopPic : System.Web.UI.UserControl
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                var currentNode = Node.GetCurrent();
                var picNode = currentNode.GetRandomChild()
                yourImg.Src = picNode.GetProperty("umbracoFile").Value;
                quoteLiteral.Text = picNode.GetProperty("quoteText").Value;
            }
        }
    }

    This code assumes you that the docs with quotes/images is childnodes to the current page, if not you can select the currentNode from its id. It also assumes you have a series of nodes of a doctype that has an upload field named "umbracoFile" for the image and a text property named "quoteText" for the text.

    Hope this will give you an idea.

    Regards
    Jesper Hauge

  • Douglas Robar 3570 posts 4711 karma points MVP ∞ admin c-trib
    Mar 02, 2010 @ 00:13
    Douglas Robar
    0

    This can also be done in XSLT.

    Here's an example that uses ImageGen to make a thumbnail of a random image. The hard-coded variables could certainly be passed in as macro variables instead.

    In my example, I was making a portfolio. I pre-loaded the full-size portfolio images into the Media section. I then added a Media Picker property to my portfolio docType for the associated image.  I put all my portfolio pages below a single content page (the $folder varaiable in my code). Then the macro could simply select a random node from below the $folder page and display the thumbnail using ImageGen to resize it to any size I wanted.

     

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:Stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <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"
    xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath"
    exclude-result-prefixes="msxml umbraco.library Exslt.ExsltMath">


    <xsl:output method="xml" omit-xml-declaration="yes"/>

    <xsl:param name="currentPage"/>
    <xsl:variable name="folder" select="1158"/>
    <xsl:variable name="thumbnailHeight" select="60"/>

    <!-- ============================================================= -->

    <xsl:template match="/">

    <xsl:variable name="imageID">
    <xsl:call-template name="GetRandomNode"/>
    </xsl:variable>

    <img alt="Portfolio">
    <xsl:attribute name="src">
    <xsl:text>/umbraco/imagegen.aspx?image=</xsl:text><xsl:value-of select="umbraco.library:GetMedia($imageID, 0)/data [@alias='umbracoFile']"/><xsl:text>&amp;height=</xsl:text><xsl:value-of select="$thumbnailHeight"/>
    </xsl:attribute>
    </img>
    </xsl:template>

    <!-- ============================================================= -->

    <xsl:template name="GetRandomNode">
    <xsl:variable name="numNodes" select="count(umbraco.library:GetXmlNodeById($folder)/node)"/>
    <xsl:variable name="random" select="floor(Exslt.ExsltMath:random() * $numNodes) + 1"/>

    <xsl:choose>
    <xsl:when test="umbraco.library:GetXmlNodeById($folder)/node [position() = $random] [string(data [@alias='umbracoNaviHide']) != '1'] ">
    <xsl:value-of select="umbraco.library:GetXmlNodeById($folder)/node [position() = $random]/data [@alias='image']"/>

    </xsl:when>
    <xsl:otherwise>
    <xsl:call-template name="GetRandomNode"/>
    </xsl:otherwise>
    </xsl:choose>

    </xsl:template>

    <!-- ============================================================= -->

    </xsl:stylesheet>

    cheers,
    doug.

  • tesuji 95 posts 139 karma points
    Mar 02, 2010 @ 21:39
    tesuji
    0

    Thanks for the replies. Very helpful

  • Arjan H. 226 posts 463 karma points c-trib
    Mar 25, 2010 @ 21:56
    Arjan H.
    0

    Be careful using the XSLT provided by Douglas. The script can cause an infinite loop, since the template GetRandomNode keeps repeating itself when it bumps into a:

    node [string(data [@alias='umbracoNaviHide']) != '1']

    The biggest problem is when you try to save the XSLT, because saving the XSLT can mysterically cause the w3wp.exe process to absorb 100% of the CPU (on /umbraco/webservices/codeeditor.save.asmx) until you recycle the application pool or restart IIS althogether. I've tested the code on multiple servers, all with the same results. Does anyone have any idea why that happens?

    I rewrote the XSLT to a very basic version that fetches a random nodeID from all pages of document type RunwayTextpage:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    
    <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" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets" 
        exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ">
    
    <xsl:output method="xml" omit-xml-declaration="yes"/>
    <xsl:variable name="documentTypeAlias" select="string('RunwayTextpage')"/>
    
    <xsl:param name="currentPage"/>
    
    <xsl:template match="/">
        <xsl:variable name="randomNodeID">
            <xsl:call-template name="GetRandomNodeID"/>
        </xsl:variable>
    
        <p><xsl:value-of select="$randomNodeID"/></p>
    </xsl:template>
    
    <xsl:template name="GetRandomNodeID">
        <xsl:variable name="numNodes" select="count($currentPage/ancestor-or-self::node[@level = 1]//node[@nodeTypeAlias = $documentTypeAlias and string(data [@alias='umbracoNaviHide']) != '1']) "/>
            <xsl:variable name="random" select="floor(Exslt.ExsltMath:random() * $numNodes) + 1"/>
    
        <xsl:if test="$currentPage/ancestor-or-self::node[@level = 1]//node[@nodeTypeAlias = $documentTypeAlias] [position() = $random]">
            <xsl:value-of select="$currentPage/ancestor-or-self::node[@level = 1]//node[@nodeTypeAlias = $documentTypeAlias] [position() = $random]/@id"/>
        </xsl:if>
    </xsl:template>
    
    </xsl:stylesheet>

  • Rich Green 2246 posts 4008 karma points
    Apr 12, 2010 @ 10:11
    Rich Green
    0

    Hi,

    Many thanks for supplying the code guys, very useful.

    Arjan, are you saying your code example has this issue as well or have you written in a way that avoids this issue?

    Doug, have you ever seen this issue with Umbraco using your code? 

    Many thanks

    Rich

  • Arjan H. 226 posts 463 karma points c-trib
    Aug 06, 2010 @ 00:27
    Arjan H.
    0

    Rich, my version of the script doesn't cause an infinite loop.

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies