Monday, February 28, 2011

Extended Content Query Web Part - 2 Column Box Layout

Before extending Content Query Web Parts (CQWP) in SharePoint refer to the following related blogs:
The following example creates a 'Highlight Box' two column layout output from a SharePoint list by applying custom XSLT styles using the Content Query Web Part.  The result looks like this:

  1. Make a copy of the SharePoint XSL stylesheets 'ItemStyle.xsl' and 'ContentQueryMain.xsl' located in the portal root Style Library (http://hostheader/Style%20Library/) and place the copies in a folder called 'Custom' within the Style Library (http://hostheader/Style%20Library/XSL%20Style%20Sheets/Custom/). Rename as 'ItemStyleExtended.xsl' and 'ContentQueryMainExtended.xsl'.

  2. Open ContentQueryMainExtended.xsl in notepad:
    1. Add the following new variables:

      <xsl:variable name="BeginListItemHighlightBoxLeft" select="string('<li class="dfwp-item highlightbox-item left">')" />

      <xsl:variable name="BeginListItemHighlightBoxRight" select="string('<li class="dfwp-item highlightbox-item right">')" />

    2. Inside the OuterTemplate.CallItemTemplate insert a new xsl choose:

      <xsl:choose>
        <xsl:when test="@Style='HighlightBoxTable'">

          <xsl:choose>

            <xsl:when test="$CurPosition mod 2 = 1">

              <xsl:value-of disable-output-escaping="yes" select="$BeginListItemHighlightBoxLeft" />

            </xsl:when>

               <xsl:otherwise>

            <xsl:value-of disable-output-escaping="yes" select="$BeginListItemHighlightBoxRight" />

          </xsl:otherwise>

          </xsl:choose>

        </xsl:when>

        <xsl:otherwise>

          <xsl:value-of disable-output-escaping="yes" select="$BeginListItem" />

        </xsl:otherwise>

      </xsl:choose>


  3. Open the ItemStyleExtended.xsl in notepad and create a new template at the end of the existing xsl:

    <xsl:template name="HighlightBoxTable" match="Row[@Style='HighlightBoxTable']" mode="itemstyle">
     
      <xsl:variable name="SafeLinkUrl">

        <xsl:call-template name="OuterTemplate.GetSafeLink">
         
    <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
       
    </xsl:call-template>
      </xsl:variable>


      <xsl:variable name="SafeImageUrl">

        <xsl:call-template name="OuterTemplate.GetSafeStaticUrl">
         
    <xsl:with-param name="UrlColumnName" select="'ImageUrl'"/>
       
    </xsl:call-template>
      </xsl:variable>


      <xsl:variable name="DisplayTitle">

        <xsl:call-template name="OuterTemplate.GetTitle">

          <xsl:with-param name="Title" select="@Title"/>

          <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
       
    </xsl:call-template>
      </xsl:variable>


      <xsl:variable name="LinkTarget">

        <xsl:if test="@OpenInNewWindow = 'True'" >_blank</xsl:if>
     
    </xsl:variable>
     
      <xsl:variable name="ImageClass" select="@Class" />


      <div class="highlight">

        <div class="highlightHead">

          <h3><a href="{$SafeLinkUrl}"><xsl:value-of select="@Title"/></a></h3>

        </div>

        <div class="highlightContentCtr">

          <a href="{$SafeLinkUrl}" target="{$LinkTarget}">
    <img align="left" class="{@Class}" src="{$SafeImageUrl}" alt="{@ImageUrlAltText}" /></a>
          <div class="highlightContent">
            <xsl:value-of select="substring(@Description,1,300)" disable-output-escaping="yes"/></div>

        </div>

      </div>


    </xsl:template
    >

  4. Update Custom.css with the following styles:

    <style type="text/css">
    li.highlightbox-item {

       width:49%;
    }
    li.highlightbox-item.left {
       float:left;
       margin-right:10px;
    }
    li.highlightbox-item.right {
       float:right;
       margin-right:0;
    }
    div.highlight {
       background-color: #f7f7f7;
       padding: 0;
       border: 0;
       margin-bottom:10px;
       border-radius-top-left:5px;
       border-radius-top-right:5px;
       -moz-border-radius-topleft:5px;
       -moz-border-radius-topright:5px;
       -webkit-border-top-left-radius:5px;
       -webkit-border-top-right-radius:5px;
    }
    div.highlight div.highlightHead {
       padding: 0.5em;
       font-weight:bold;
       background-color: #e4e4e4;
       border-radius-top-left:5px;
       border-radius-top-right:5px;
       -moz-border-radius-topleft:5px;
       -moz-border-radius-topright:5px;
       -webkit-border-top-left-radius:5px;
       -webkit-border-top-right-radius:5px;
    }
    div.highlight div.highlightHead h3 {
       margin:0;
    }
    div.highlight div.highlightContentCtr {
       min-height:50px;
       border: 1px solid #e4e4e4;
       border-top:0;
    }
    div.highlight div.highlightContentCtr img {
       margin: 0 10px 0 0;
       border: 0;
       padding: 0;
    }
    div.highlight div.highlightContentCtr img.icon {
       width:50px;
       height:50px;
    }
    div.highlight div.highlightContentCtr img.image {
       width:75px;
       height:50px;
    }
    div.highlight div.highlightContent {
       padding: 10px 10px 4px 10px;
    }
    </style>


  5. Add a Content Query Web Part (CQWP) to a page. Do not configure it in any way.

  6. Export the Content Query Web Part to your desktop.



  7. Open the exported CQWP in notepad and edit the following properties:

    <property name="Title" type="string">Extended Content Query</property>

    <property name="ItemXslLink" type="string">/Style%20Library/XSL%20Style%20Sheets/Custom/ItemStyleExtended.xsl</property>


    <property name="MainXslLink" type="string">/Style%20Library/XSL%20Style%20Sheets/Custom/ContentQueryMainExtended.xsl</property>

  8. On the web part page where you would like the CQWP displayed, select Edit, Add a Web Part, Upload a Web Part:


  9. On the web part page where you would like the CQWP displayed, select Edit, Add a Web Part, Imported Web Parts, Extended Content Query


  10. Edit the Extended CQWP properties:
    1. In the properties panel expand the Query node. Select the radio button Show items from the following list and enter the path to the associated SharePoint list, (which requires six columns including: Title, Image, Description, URL, Class and Order). Apply these changes by selecting the Apply button at the bottom of the properties panel.

    2. Expand the Presentation node and in the Grouping and Sorting section set the Sort items by to ‘Order’.



    3. In the Styles section set the Item style to HighlightBoxTable.
    4. In the Fields to display section set as in the screenshot.



    5. Expand the Appearance node and set the Chrome to none.
    6. Select Ok.

    18 comments:

    1. Excellent Post. Is it possible to have GroupBy on two columns in CQWP ? I have used QueryOverride option to accomplish this but it is working only partially. The CQWP does not display the second GroupBy column value though the items are displayed according to the GroupBy on both. How do I do that ?

      ReplyDelete
    2. I have used QueryOverride to GroupBy on additional column instead of the default one allowed. However, CQWP displays only first group
      header though the results are in the order of GroupBy first and then second column. How do I change the XSL in order to display the second GroupBy column value also as header ?

      ReplyDelete
    3. where is that Custom.css supposed to go?

      ReplyDelete
    4. You could place your CSS in your portal Style Library (located in the site collection root via the 'View All Site Content' link) or alternatively in the server layout directory for example:
      C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\yourportal\CSS...

      ReplyDelete
    5. Thankyou for your quick response. i tried 3 times and all three times gave me error. is it possible you can share your 'ItemStyleExtended.xsl' and 'ContentQueryMainExtended.xsl' files? i think i am not doing something right. Actually i was trying this in SharePoint 2010. I really appreciate your great help.

      ReplyDelete
    6. Hi Prakash - I have added the code snippets for both files here:

      http://www.bytelab.co.uk/extended-content-query-web-part-2-column-box-layout/

      These are used in a SharePoint 2010 environment.

      ReplyDelete
    7. https://sites.google.com/site/coresoul/extended-content-query-web-part

      Please look at those files. i am doing anything wrong?

      ReplyDelete
    8. Check your XSL - the syntax in your styles looks incorrect at the line: <xsl:when test=""LinkUrl = ""> should be: <xsl:when test="@LinkUrl = ''">

      ReplyDelete
    9. Thank you so much! These instructions helped a lot when trying to find a way to display clickable images horizontally in my CQWP.

      ReplyDelete
    10. Thanks for the guide!. Helped a great deal.

      However, i still cannot figure out where the custom.css is referenced either in the 'ItemStyleExtended.xsl' or 'ContentQueryMainExtended.xsl' files.

      I have followed the steps and still get an error partly because the step about updating the Custom.css file is vague. ('Updating' would mean that the file existed initially). Kindly clarify.

      ReplyDelete
    11. @Basil Nwogu - wherever you usually keep any custom css applied to your site - this could either be in the SharePoint file system ie: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS or in the site collection in the Style Library

      ReplyDelete
    12. Hello Bytelab,

      I have a very simpler requirement. On the results of content query web part I want to display the results as

      Icon Title Description ModifiedBy ModifiedDate
      Doc Data somebody somedate


      I am querying a document library. The problem is queried data is returned in only one column by default as

      Doc1
      Data
      Somebody
      Somedate

      Doc2
      Data2
      Somebody2
      Somedate2

      I need the headernames too

      Bob

      ReplyDelete
    13. Thank you so much for this post. Really. :-) Incredibly useful. Saved me a bunch of time.

      ReplyDelete
    14. Hi Hannah,

      Thanks for the excellent post.

      I've followed the steps, and have got the content editor look similar to yours but it does not show two columns. The only thing I've done differently(as far as I can see) is that I haven't added a class column, as I didn't understand what type of column it is and what it does. Could you please let me know what I could be missing?

      Thanks and Regards,
      Manu

      ReplyDelete
    15. Found the issue, it was the location of xsl:choose in OuterTemplate.CallItemTemplate. When I placed it towards the beggining it started working as expected.

      Thanks,
      Manu

      ReplyDelete
    16. In SPD you have to replace HTML < " > with < &quote; $gt; respectively.

      ReplyDelete
    17. Hannah, the post is fantastic and i was really looking to find something similar. I've followed your steps but unfortunately somewhere, somehow i probably get something wrong and the layout doesn't show two columns. My hunch is that it's related to the OuterTemplate.CallItemTemplate and the location of the xsl:choose inside it. I have played with several options and the closest i got to the two columns was when i place it in between:

      xsl:template name="OuterTemplate.CallItemTemplate"
      xsl:param name="CurPosition" /

      AND

      xsl:value-of disable-output-escaping="yes" select="$BeginListItem" /

      Any help would be highly appreciated.

      Many thanks,
      Andi

      ReplyDelete
      Replies
      1. Hi Andi - my code sits in the xsl between:

        xsl:param name="CurPosition" /

        and

        xsl:value-of disable-output-escaping="yes" select="$EndListItem" /

        Delete