Get Random Item from XSLT Rendering


Had a request to write an XSLT Extensions that can select a random child of an Item.  I wrote this extension that takes in a Sitecore Query and randomly selects one of the times. You could use it to do something like randomly display a Teaser from a Teaser Folder.

After compiling the code you will have to register the XSLT extension in your web.config file and add the namespace to the top of your XSLT Transformation.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sitecore.Xml.Xsl;
using Sitecore.Data.Items;
using System.Xml.XPath;
using Sitecore.Configuration;
using Sitecore.Xml.XPath;

namespace Sitecore.Prototypes.Client.Xslt
{
    public class Extensions : XslHelper
    {
        private static readonly XPathNavigator emptyNavigator;
        private static Random randomInstance = new Random();

        public XPathNodeIterator GetRandomResult(string query)
        {
            Item[] items = Sitecore.Context.Database.SelectItems(query);
            if (items != null)
            {
                int skip = randomInstance.Next(items.Count());
                try
                {
                    Item item = items[skip];
                    if (item == null)
                    {
                        return CreateEmptyIterator();
                    }
                    ItemNavigator navigator = Factory.CreateItemNavigator(item);
                    if (navigator == null)
                    {
                        return CreateEmptyIterator();
                    }
                    return navigator.Select(".");

                }
                catch (Exception e)
                {
                    Sitecore.Diagnostics.Log.Fatal(e.Message, this);
                }
            }
            return null;
        }
        private XPathNodeIterator CreateEmptyIterator()
        {
            return emptyNavigator.Select("*");

        }
    }
}

Sitecore Ribbon that displays published state of an item


To see if an item is published in Sitecore I would normally have to switch to the ‘web’ database and browse to the item. I created a ribbon panel that shows the ‘Status’ of an item in the ‘web’ database from the ‘master’ database.

View of Published Status

It displays the version number published for each language or tells you the item has not been published.

Here’s the code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sitecore.Shell.Web.UI.WebControls;
using Sitecore.Diagnostics;
using Sitecore.Data.Items;
using Sitecore.Data;

namespace Sitecore.Prototypes.WebControls.ContentEditor.Panels
{
     public class PublishingInfo : RibbonPanel
    {
         public override void Render(System.Web.UI.HtmlTextWriter output, Web.UI.WebControls.Ribbons.Ribbon ribbon, Data.Items.Item button, Shell.Framework.Commands.CommandContext context)
         {
           Assert.ArgumentNotNull(output, "output");
           Assert.ArgumentNotNull(ribbon, "ribbon");
           Assert.ArgumentNotNull(button, "button");
           Assert.ArgumentNotNull(context, "context");
           if (context.Items.Length >= 1)
           {
               Item contextItem = context.Items[0];
               Database database = Sitecore.Configuration.Factory.GetDatabase("web");

               Item item = database.SelectSingleItem(contextItem.ID.ToString());
               
               string htmlOutput = string.Empty;
               if (item != null)
               {
                   
                   foreach (var language in item.Languages)
                   {
                       Item languageVersion = item.Versions.GetLatestVersion(language);
                       if (languageVersion != null && languageVersion.Versions.Count > 0)
                        {
                            htmlOutput += string.Format("<div>{0} - {1}</div>", languageVersion.Version.Number.ToString(), languageVersion.Language.GetDisplayName());
                        }
                   }
                   
               }
               if (htmlOutput == string.Empty)
               {
                   htmlOutput = "This item is not currently published.";
               }

               htmlOutput = string.Format("<div class='scRibbonToolbarText' style='overflow-y:scroll;padding-right: 20px;font-size:80%;'><div style='font-weight:bold'>Published to Web</div>{0}</div>", htmlOutput);

               output.Write(htmlOutput);
           }

           
         }
    }
}

To configure it :
1. Switch to Core database
2. Browse to /sitecore/content/Applications/Content Editor/Ribbons/Chunks/Publish
3. Insert a new /sitecore/templates/System/Ribbon/Panel
4. See the type according to your class name and assembley
sample : Sitecore.Prototypes.WebControls.ContentEditor.Panels.PublishingInfo, Sitecore.Prototypes.WebControls

Building a Sitecore Base Page Template


Sitecore is a Web Content Management system on the C# Microsoft .Net framework. If you’re not familiar with it then this posts isn’t going to make much sense to you.  I’m playing around with the it for fun and thought I’d throw out there what your basic page template should look like from both a C# and Sitecore point of view .

If something in Sitecore has a Layout(.aspx) then it’s almost always a Page. I say almost always because I’ve played around with using a page to stream a resource as a lazy mans http handler but I didn’t roll that to a production site and later rewrote it to be use a HTTP Handler.

Pages all have some basic things so why not build a base page template and a base C# Class to support these functions.

Video Demo

I’ll give some guidance on how to implement it, feel free to give your own thoughts and throw out some things I could be missing in the comments.

Title : Every Page has a title. This is the text that shows up in the top of the browser window.

Description : At a minimum you want this for SEO. It’ll show up as the text next to your link in a search engine if gets indexed. Maybe your page will get indexed, maybe it won’t, but leave that up to the business and content authors to decide and make sure you have code in there to support it.  A lot of navigation controls have items next to them with some short description text. So you can use this in some of your own display modules.

Keywords: Another thing you want for SEO but it may also come in handy if you want to some day implement search within your site.

Show in Navigation : At some point you’re going to build out navigation objects and you are going to want to check to see if the item should be shown in the menu. Rather than code against template types you can just check to see if the item inherits the ‘Page’ template and check to see if this option is checked.

Navigation Image : This can be used to display an image that represents the page as part of some type of navigation area. Might need a large and a small depending on requirements but if you have none I say it’s worth it to put something in at 30 by 30.

CSS and Javascript Files: In an ideal solution you have code with CSS and Javascript that stays on the server that belongs to the programmers and you have seperate CSS and JS script files that belong to the Content Authors that is seperate from the developers code.  If you can store this in sitecore you can deploy these objects without needing to push code to a server. In some enviornments that takes time. You wouldn’t believe how many times someone in marketing tells me they got a javascript api they’d like to implement on some pages today and they can’t wait for a release so they are pasting a ton of javascript into a html field.  This will give them a place to put the javascript that they can reuse without waiting for a build. I’d like CSS in there because I think a talented author could do a lot with it.

Read more of this post