Embed CAML Queries into the Content Query Webpart - Finding Draft Publishing Content

In a recent article I demonstrated how to use recursion to show the publishing status of my publishing pages. This is a great technique, because a natural progression from there is being able to manipulate those same publishing pages’ properties you accessed through recursion. This can manage a number of issues as I will discuss in a forthcoming article. 

Today however, I want to demonstrate a code free way of showing the publishing page status. We will embed a CAML query into the wonderful Content Query Web Part, that will show the same information. This isn’t a CAML tutorial, but a demonstration of an effective technique to unleash the potential of the CQWP. CAML, or Collaborative Application Markup Language is a very powerful tool used extensively in Sharepoint for data definition and rendering. A comprehensive introduction can be found here http://msdn2.microsoft.com/en-us/library/ms426449.aspx .

In today’s example we will be borrowing a pre-defined CAML query to return a list of publishing pages that are in a draft state. The CAML we need is already included as standard in the default MOSS install. If you go to the Site Actions menu -> View Reports -> All Draft Documents  you are redirected to the Site Content and Structure pages, and all items that meet the report criteria in the current site are displayed. This report is defined in MOSS as a CAML query, which we can take a look at. Navigating to top level site in ‘Site Content and Structure’ you’ll see a list called ‘Content and Structure Reports’. Clicking this shows a list of CAML queries that equate to the same reports you saw displayed via Site Actions. The All Draft documents report should contain a CAML Query that looks like this;  

<Where><Eq><FieldRef ID="{fdc3b2ed-5bf2-4835-a4bc-b885f3396a61}"></FieldRef><Value Type="Number">3</Value></Eq></Where>

 

 You could summarise this query as ; Display fields where the FieldRef that has an ID = GUID has a value of 3.  

What the heck field does that GUID relate to? It’s tp_ModerationStatus from the AllUserData table, for anyone familiar with the MOSS Content Database structure.  The field has the following documentation in MSDN at http://msdn2.microsoft.com/en-us/library/ms998711.aspx ; 

tp_ModerationStatus int Value that specifies the status of a list if it is moderated. 0 is approved; 2 is pending; 1 is rejected.

 

 Nothing like full documentation is there? So what is 3?! Draft is 3, not that they tell you that.  

So, our CAML query is returning references to content that is draft. This includes publishing pages, and uploaded documents. You’re probably guessing already that with something as powerful as CAML we could refine this a lot more. How about draft content of a specific Content Type? Well, the content type column in AllUserData is of ID c042a256-787d-4a6f-8a8a-cf6ab767f12d so you can easily construct a CAML query to meet your needs. (This article is more about embedding CAML than writing it though, so time to get back on track). 

OK, now we’re happy with what our query does, it’s time to use it, by embedding it into a CQWP.  

Open the publishing page you want to use this at. It should have a web part zone.

Follow these steps; 

1. Place the standard CQWP onto the page.

2. Export the web part (in the web part pane, click edit -> Export and save the file to your PC)

3. Open the webpart you just exported in Notepad or some other plain text editor

4. Find the property <property name="QueryOverride" type="string">

5. Embed your CAML query into a CDATA section, the above query will now look like this; 

<![CDATA[<Where><Eq><FieldRef ID="{fdc3b2ed-5bf2-4835-a4bc-b885f3396a61}"></FieldRef><Value Type="Number">3</Value></Eq></Where>]]> 

6. Place this CAML into the QueryOverride property in the webpart. That line of markup should now look like this; 

<property name="QueryOverride" type="string"><![CDATA[<Where><Eq><FieldRef ID="{fdc3b2ed-5bf2-4835-a4bc-b885f3396a61}"></FieldRef><Value Type="Number">3</Value></Eq></Where>]]></property> 

7. Save the webpart text

8. Import the webpart back into Sharepoint. Click ‘Add a Web Part’ in the web part zone of the page ->Advanced web part gallery and options -> Browse -> Import. Select your modified .webpart file that you saved to your PC.

9. An icon for your webpart will appear in Sharepoint. Drag that into the webpart zone you want this to appear in.

10. Check in your page, and see the results. 

That’s it! The webpart is now displaying details of draft documents and pages to anyone with the necessary credentials.  Do check out the settings of the CQWP. You can make major customisation to what is displayed. Number of items, and starting location of search being of most interest to me. 

Finally, if you’re still not too confident in writing CAML queries, there are loads of CAML generators around for free. Search for CAML on www.codeplex.com and you’ll be in business.

UPDATE; In response to some reader queries, I've written a further article detailing how to override the default fields that CQWP outputs. The example displays all Checked Out and Draft documents for users and includes some commentary on using Caching and Audiences with your CQWP. The new article is here; https://jamiemcallister.com/Further-Customise-CQWP-to-Display-Draft-and-Checked-Out-Pages-By-User