Cleaning Up the SharePoint Content Query Webpart Output w/ Option to Render in Columns

I want to start off by giving credit where credit is due because nothing truly is from scratch anymore. If you need something – chances are someone out there has already been through all the headaches to get there or at least has done something similar and gives you that little nugget of information that helps you get over the mountain. There were 2 articles that I found that really sparked this whole coding adventure.


The Problem

For the most part the output of the SharePoint content query web part (CQWP) is sufficient. But in some cases the additional unordered list HTML might cause some styling headaches if you need things to be in the same parent container or need all of the items to be rendered one right after the other; not in separate <li>’s. I wanted to give the option to clean up the output and render the items in columns but not take away any of the normal functionality of the CQWP – mainly the grouping.

The Solution

  • CQM-v3.0 – replace your whole /Style Library/XSL Style Sheets/ContentQueryMain.xsl file with the contents of this – every line that I’ve added or edited is commented with detail
  • Item Style – use this as a template for any item styles you want to clean up and output into columns – just make sure all the item styles you want to ‘clean up’ have the prefix ‘clean-‘
  • CQM-O365-v1.0 – this is the O365 version
  • clean-CQWP-columns – originally I had the CQM file setting an inline width on the columns – this was ok but ran into some projects since that required responsive styling so I removed the inline styles from the CQM and added this in an external JS file…\the function when called needs a breakpoint set where the columns collapse on mobile devices – if you never want them to collapse you can set that value to 0 (zero)
  • SummaryLinkMain – replace your whole /Style Library/XSL Style Sheets/SummaryLinkMain.xsl file with the contents of this

UPDATE HISTORY

  • 5/19/2015
    • update SummaryLinkMain.xsl – fixed error on Summary Links Web Parts when the itemstyle is added to the itemstyle.xsl (because of missing templates that are being called)
  • 12-15-2014
    • added O365 support
    • added responsive JS

OOTB vs New ‘CLEAN’ Output

This is an example of OOTB rendering of items. Seems fine right?

ootb-cqwp-output-1

The HTML however is a bit too much for just this…

ootb-cqwp-output-2

Take a look at how much cleaner the HTML is for the same items – using the new item style.

clean-cqwp-output

Here is the output the item style produces with 4 columns.

clean-cqwp-output-2

…and with grouping.

clean-cqwp-output-3

…and with more than 1 column set in grouping.

clean-cqwp-output-4


Item Style Explanation

In Peter’s article about building columns all the calculations were done in each item style. His was fine as far as code length goes but as I was adding variables for grouping the item style eventually swelled to about 150 lines long. I decided to break all the calculations out into templates for the HTML surrounding the actual item output. So all of that is done in the ContentQueryMain.xsl by passing variable data back to the main xsl.

You will specify the number of columns you want in your output by changing this parameter number. (It’s in 2 places in the item style – where it calls the clean-item-header template and the clean-item-footer template)

<xsl:with-param name="columns" select="4" />

The hidden variable that stores the value of the site column @GroupByName updates the XML of the CQWP to be used in the ContentQueryMain.xsl document to help with grouping variables. This must remain in each of your item styles so that the field name can be updated in the CQWP edit panel.

groupname


How I Kept the Grouping Functionality

With the detailed articles I credited above and all my comments in the xslt documents I didn’t feel the need to go into full detail on what is going on behind the scenes with optimizing the output of the CQWP. But I DID want to talk about how I was able to keep the grouping functionality.

The way the column output (without grouping set in the CQWP) works, is it counts the TOTAL number of items, divides it by the number of columns set and splits the items up appropriately by calculating it’s current position. So the challenge here was to be able to count the items PER GROUP to set as the TOTAL for each, divide each of those by the number of columns and then use the current position again to split up into separate columns within each group.

Unfortunately using position() alone wasn’t going to cut it because items in separate groups kept their position sequentially from the previous groups. Like this…

group-position

What it should be is this…where the position of the item resets to 1 and continues per group.

group-position-2

There were 3 main pieces to this puzzle that made all of this possible – the KEY, a variable to count TOTAL ITEMS PER GROUP and a variable to count TOTAL PRECEDING GROUPS ITEMS.

The KEY that I’m targeting is the @GroupByName attribute of each ROW node – (remember @GroupByName comes from the hidden variable in the item style that allows you to specify the site column you are grouping on – it becomes an attribute in CQWP xml).

groupbyname-key

The TOTAL ITEMS PER GROUP template uses Muenchian grouping to count items per group. It references the KEY as it cycles through the items and only counts the items if they have the same @GroupByName category. We call this template later during the item build.

itemspergroup

To count the TOTAL PRECEDING GROUP ITEMS I created a template to be called later so that I could pass the name of the @GroupByName of the current item. Counting the TOTAL PRECEDING GROUP ITEMS allows us to take the current position of our item and subtract the number of items in the previous groups so that we can mathematically reset the position to 1 in EACH group. So for example if the current position is 4 but is in the second group we would take 4 and subtract the 3 items in the previous group to get 1, if the current position is 9 but is in the second position in the third group we would take 9 and subtract the 7 items in the previous groups to get position 2 in the third group.

precedingitems

The rest of the magic is done in the header and footer templates when called from the item style. Those templates use variables passed from the item style as well as the global variable $cbq_isgrouping that is set at the top of the ContentQueryMain.xsl to determine which total item value or current position values to use.

header-template


GOOD LUCK!!!!

Please comment with any questions, suggestions, success stories of using it, etc.

You may also like...

2 Responses

  1. Nishita says:

    Hi Sonny,
    I want to group by ‘Author’ in content query web part and also want total items per group.
    Please tell me how to do this.

    • Sonny says:

      Hi Nishita – sorry for the delayed response – I have been bombarded with spam comments so it’s been difficult to sift through all the legitimate ones

      anyway

      you should be able to just use the Author column in the grouping field of the CQWP – is that not an option in the web part properties?

      for total items you should be able to call the template from within your itemstyle to get the number – please try using



      thanks! please let me know if you need any further help

Leave a Reply

Your email address will not be published. Required fields are marked *

nineteen + seventeen =