August 10, 2011 07:00 AM

Randomizing SharePoint’s Content Query Web Part

It’s not a flying hot dog, but the CQWP is pretty cool
SharePoint Pro
InstantDoc ID #136380
Rating: (0)
Downloads
136380.zip

Imagination and versatility are a powerful combination. As the parent of a 2-year-old son, I’m reminded of that almost daily. He’s constantly innovating, and almost any object you hand him to play with will suddenly have a range of new uses you never imagined. If you’ve ever seen a hot dog become an airplane or watched an orange fly through a basketball net, you know exactly what I mean.

Although I would never dare compare Microsoft Office SharePoint Server’s Content Query Web Part (CQWP) with a hot dog flying through the air, I can’t ignore the fact that it, too, possesses a wide range of uses. Using a little imagination, I’ve found that the CQWP covers an amazing number of scenarios.

One such case came up on a project I was working on recently. We were building a corporate intranet with SharePoint Server 2010, and the client requested that we randomly display some items on the home page from one of their lists. Technically, it was a little more complicated than that, because there was a notion of active vs. inactive items and some other minor details, but the point is that we needed to randomly choose the items that got displayed. We knew the CQWP would be a good fit for querying the list items and formatting them for display, but we needed a way to randomize it. In this article, I discuss the approach I took to solve the problem, and I explain the reasoning behind some of the design decisions I made.

 

Solving the Problem with XSLT

To get started, I did a quick web search to see if anyone else had already done something similar. I didn’t find much that was useful except a couple of blog posts that solved a similar problem with Extensible Style Language Transformations (XSLT). I say “similar” because they were displaying only a single random item at a time (typically an image). I needed to display a set.

The approach in the blog posts was to create a custom XSLT extension function (similar to the ddwrt:FormatDate function that’s often used to format dates) and register it with the CQWP for use in Extensible Stylesheet Language (XSL). The function was a simple random number generator that returned a value between 1 and the number of query results being iterated in the XSL. When the function was called, the random number it returned was used as an index into the query results, and only that particular result was displayed.

If I had used that approach, registering an XSLT extension function with the CQWP isn’t difficult. Suppose, for example, that I wanted to create my own ToUpper function that let me convert a string to uppercase. First, I’d create a class with my extension function, as Listing 1 shows.

Next, I’d register an instance of that class with the CQWP as an XSLT extension object (i.e., a type of object that extends normal XSLT functionality). To do that, I’d override the ModifyXsltArgumentList() method of the ContentByQueryWebPart class, as Listing 2 shows. Within that method, I’d call AddExtensionObject() on the argList parameter that’s passed in and register my extension object with a custom namespace.

On the XSL side, I could access the extension object’s methods as extension functions by adding a namespace declaration, like so:

xmlns:custom=urn:my-xslt-extensions 

Then, I could convert a string to uppercase by calling the function, like so:

<xsl:value-of select="custom:ToUpper(@Description)" /> 

As you can see, creating and using custom extension functions in XSLT isn’t all that difficult. And although I could’ve used this approach to generate random numbers and use them in XSL, as in the blog examples I’d seen, this solution wasn’t quite what I was looking for. I was looking for a more generic approach that would work even with the out-of-box XSL files provided by SharePoint. Custom extension functions would mean deploying custom XSL files, and I wanted to avoid doing so if possible—which left me with one other option: Randomly choose query results before rows are passed to the XSL transform for display.

Solving the Problem without XSLT

Solving the problem without XSLT meant intercepting the query results before they were passed to the XSL transform, randomly selecting some of them, and passing only those results to the transformation process. Intercepting query results in the CQWP means using the ProcessDataDelegate property. ProcessDataDelegate is a property on the ContentByQueryWebPart class that allows a method to be assigned that can intercept and process query results before they’re transformed.

I created a new class that inherited from ContentByQueryWebPart and assigned a method to the ProcessDataDelegate property in the constructor. Listing 3 shows the method I created. As you can see in the code, I didn’t bother creating a second DataTable and copying rows into it. I simply removed the rows I didn’t want from the original table and returned whatever was left. The key here was generating multiple, unique random numbers for selecting the rows to return. I wrote the GetUniqueRandomIndexes method to do just that, as Listing 4 shows.

Related Content:

ARTICLE TOOLS

   
Comments
    There are no comments to display. Be the first one!
You must log on before posting a comment.

Are you a new visitor? Register Here
   
   

Dan Holme's Viewpoint on SharePoint Blog

Office 365 Plan for Pain

With cloud services, even Office 365, what you don’t know about your cloud service can hurt you,...

SharePoint News and Products

Let SharePoint Be SharePoint: Making Social Collaboration Secure

Hesitant about unleashing SharePoint's social features? SharePoint security vendors aim to help....

Dan Holme's Viewpoint on SharePoint Blog

Microsoft SkyDrive Updates in the News

Microsoft's cloud storage, sharing, and collaboration platform for Windows Live is updated,...