Copied to clipboard

Flag this post as spam?

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


  • Dan Christoffersen 64 posts 119 karma points
    Jul 13, 2009 @ 10:38
    Dan Christoffersen
    0

    Select 3 random pages from a specified folder

    I am building a website with a panel on every page which shows an abstract of 3 random pages from a special "abstract" folder.

    The idea is that the pages in the "abstract" folder is never shown "as is", but the content is extracted and embedded in a panel on the public pages of the website.

    So, what I have been trying to do, is to make a dot.net component macro that does this, but i have not found a way to do it. It might be pretty simple to do, but I'm new to both Umbraco and dot.net, so I thought I better turn to the Umbraco community for a little help.

    Tnx in advance,

    Dan

  • vladzebu 59 posts 346 karma points
    Jul 13, 2009 @ 11:07
    vladzebu
    0

    You can create a xml extension for generating 3 diferent items from a number of items . 

    You have now the id of the items and you can render on the panel .

    Best regards , Vlad . 

     

  • Bogdan 250 posts 427 karma points
    Jul 13, 2009 @ 11:20
    Bogdan
    0

    Hi,

    you don't have to make a .net user control for that, you can use xslt. First, make a property to your "abstract" node called umbracoNaviHide of type True/False so you can hide the node from navigation. This property is just a convention to be used in situations like this, you can name it any way you want, but chances are if you used some sample xslt to create your menus this umbracoNaviHide is already used there. Then you can make an umbraco macro with an xslt that gets 3 random nodes from your abstract node, this an example (that I found somewhere on this forum) on how to get a random node:

    <xsl:variable name="abstractNode" select="abstractNodeId"/>

    <xsl:variable name="abstractNodeSet" select="$abstractNode/descendant::node[@nodeTypeAlias = 'AbstractChildNodeTypeAlias']" />
    <xsl:variable name="numNodes" select="count($abstractNodeSet)" />
    <xsl:variable name="randomNum" select="floor(Exslt.ExsltMath:random() * $numNodes) + 1"/>
    <xsl:variable name="randomNode" select="$abstractNodeSet[position() = $randomNum]"/>

    then you can use the node $randomNode to output whatever of its properties you want. I'll of course have to change abstractNodeId to the id of your abstract node, and AbstractChildNodeTypeAlias to the alias of the child nodes of the abstract node. Load this macro in any templates you want and you're done! Let me know if need any more detais on this, I'm also kind of new to umbraco, but I did a similar xslt to the one I think you need.

  • Dan Christoffersen 64 posts 119 karma points
    Jul 13, 2009 @ 12:51
    Dan Christoffersen
    0

    Thanks for your replies.

    Xslt is kind of a mess to right now - and i definatly feel more at home using dot.net. But if I decifer your example right, the trick is to loop the above example 3 times to get 3 random nodes. But in that way, I have no way (that I know of) to make sure the node is not already been taken. Put another way: I need 3 random, but distinct nodes. Any way to this?

  • Bogdan 250 posts 427 karma points
    Jul 13, 2009 @ 16:30
    Bogdan
    0

    Yeah, you do have a good point, I don't know if you can make the 3 random nodes distinct, at least not by using my example. If you want to make a .net user control, then you should do some research on how to use the nodeFactory class from the umbraco.presentation package, it provides read-only methods, but it's fast.

  • Paul Blair 466 posts 731 karma points
    Jul 15, 2009 @ 01:28
    Paul Blair
    0

    Hi,

    This is how I select a random node by calling our to .NET from XSLT. You should be able to modify to pass in a array of already selected integers to ensure you don't reuse a node.

    [code]

    <?xml version="1.0" encoding="UTF-8"?>

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxml="urn:schemas-microsoft-com:xslt"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:umbraco.library="urn:umbraco.library"
    xmlns:yourprefix="urn:my-scripts"

    exclude-result-prefixes="msxml yourprefix umbraco.library">

      <xsl:output method="html"/>
      <xsl:param name="currentPage"/>

      <msxsl:script implements-prefix='yourprefix' language='CSharp'>
        <![CDATA[
    public int randomNode(int limit)
    {
    DateTime tmeNow = DateTime.Now;
    int mls = tmeNow.Millisecond;
    Random rndNumber = new Random(mls);
    return rndNumber.Next(1, limit + 1);
    }

    ]]>
      </msxsl:script>

      <xsl:template match="/">
        <xsl:variable name="AdGroup" select="/macro/source/node/@id"/>
        <xsl:variable name="collection" select="umbraco.library:GetMedia($AdGroup, 'true')/node"/>
        <xsl:variable name="selectedNode" select="yourprefix:randomNode(count($collection))"/>

        <xsl:for-each select="$collection">
          <xsl:if test="position() = number($selectedNode)">
            <img>
              <xsl:attribute name="src">
                <xsl:value-of select="./data[@alias='umbracoFile']"/>
              </xsl:attribute>
              <xsl:attribute name="alt">
                <xsl:value-of select="@nodeName"/>
              </xsl:attribute>
            </img>

            </xsl:if>
        </xsl:for-each>

      </xsl:template>
    </xsl:stylesheet>

    [/code]

  • Dan Christoffersen 64 posts 119 karma points
    Jul 15, 2009 @ 16:46
    Dan Christoffersen
    0

    This is what i finally have come up with.

    Now, there might be some easier way to do this, but as mentioned earlier, I'm pretty inexperienced with c#, not to mention Umbraco.

    Any suggestions on improvements are highly appreciated.

    The code:

        public partial class CasePanel : System.Web.UI.UserControl
    {

    public int parentId { get; set; }
    public int nodeCount { get; set; }

    private Random index = new Random((int)DateTime.Now.Ticks);

    protected void Page_Load(object sender, EventArgs e)
    {
    umbraco.presentation.nodeFactory.Nodes nodes = new umbraco.presentation.nodeFactory.Node(parentId).Children;

    if (nodes.Count < nodeCount) nodeCount = nodes.Count; //Make sure count is not greater than the actual number of nodes

    Node[] nodeList = new Node[nodeCount];

    selectRandom(nodes, nodeList, 0);
    for (int i = 0; i < nodeCount; i++)
    {
    Literal1.Text += nodeList[i].Name + "<br />";
    }

    }

    void selectRandom(Nodes list, Node[] newList, int cursor)
    {
    Node node = list[index.Next(list.Count)];

    if (!newList.Contains(node))
    {
    //The node is NOT in the list - append it.
    newList[cursor] = node;
    cursor++;
    }

    if (cursor < newList.Length)
    {
    selectRandom(list, newList, cursor);
    }

    }

    }

Please Sign in or register to post replies

Write your reply to:

Draft