My client recently asked for a simple user control that would show which publishing pages were checked out. The idea being a one stop shop to find unpublished pages, and publish them! This gives me a good excuse to demonstrate a very powerful technique that can be applied to Sharepoint problems; that of recursion.  (As an aside, I've done another article that solves the same problem using CAML. You can check that out here https://jamiemcallister.com/post/Embed-CAML-Queries-into-the-Content-Query-Webpart---Finding-Draft-Publishing-Content.aspx but stick with this article on Recursion as it's a powerful technique you'll want to use often!).

Data in Sharepoint is stored in a hierarchical structure. It’s straightforward to write software that will navigate through that structure and find items of interest. I want to find all my publishing pages and check what state they are in. For this example I’m writing an ASP.NET user control that I can put on a page, and will interrogate every folder that has publishing pages in it. The page name will be displayed, along with a link to the page, and its checkout status.

This code is so simple that it doesn’t warrant a detailed explanation, see the full code listing lower down. I’ve added a bit of html formatting in the control for the output. I’m sure you can do a better job of that! 

One item of note is the SPFileLevel enumeration (SPListItem.File.Level). This has values of Published, Draft, or Checkout. So that’s the degree of granularity we can report on. OK, anyway, here’s the code; 

<script runat="server">    

StringBuilder sb = new StringBuilder();      

void Page_Load(object sender, EventArgs e)   

{      

     GetCheckedOutFiles(System.Web.HttpContext.Current.Request.Url.AbsoluteUri);   

}       

void GetCheckedOutFiles(string startingUrl)   

{       

     sb.Append("<table class='ms-informationbar'><tr><td>Page</td><td>Current Status</td></tr>");       

     using(SPSite site = new SPSite(startingUrl))       

     {           

          using(SPWeb web = site.OpenWeb())           

          {               

               RecursePublishingWebs(web);                                   

          }       

      }       

sb.Append("</table>");   

}    

void RecursePublishingWebs(SPWeb web)   

{       

     if (PublishingWeb.IsPublishingWeb(web))       

     {           

          IteratePublishingFiles(web);       

     }               

     foreach (SPWeb subWeb in web.Webs)       

     {           

          RecursePublishingWebs(subWeb);       

     }   

}    

void IteratePublishingFiles(SPWeb web)   

{       

     Guid pagesListId = PublishingWeb.GetPagesListId(web);        

     //Get the list by using the ID       

     SPList pagesList = web.Lists[pagesListId];       

     foreach (SPListItem item in pagesList.Items)        

     {              

          sb.Append("<tr><td>");              

          sb.Append("<a href='");              

          sb.Append(item.Web.ServerRelativeUrl);              

          sb.Append("/");              

          sb.Append(item.Url);              

          sb.Append("'>" + item.Name + "</a>");              

          sb.Append("</td><td>");              

          sb.Append(" [" + item.File.Level + "]");              

          sb.Append("</td></tr>");       

     }   

}

</script> 

<div style="overflow:auto;width:400px;height:200px">

<b>Checked Out Pages;</b> <br /><br />   

<%= sb.ToString() %>

</div>