Displaying the Most Recent Documents from All Document Libraries in a SharePoint Site

Data View Web Parts (DVWPs) are still my favorite tool in my SharePoint toolbox. Whenever I can use them to get the server to do the heavy lifting before the page is rendered, I do. jQuery and all of the fancy template libraries out there are grand, but in most cases it introduces a lag for the user between the time the page shows up in the browser and the time they can see all of the content.

In this case, I wanted to show the most recently modified documents in each of the Document Libraries in one site on that site’s home page. A DVWP using DataSourceMode=”CrossList” is a great way to do this. By using this method, any new Document Libraries will simply show up in the DVWP as soon as they are added. There’s no need to change any code at all.

I don’t usually like to just give the full code to something because I think it’s more beneficial to show the pieces so that you, gentle reader, must adapt things to your own environment and particular business needs. Given the neutered state of SharePoint Designer 2013, though, I think I’ll probably post full DVWPs where I can going forward. It’s simply too darn hard to edit DVWPs in SPD2013. Here I was working in SharePoint 2010, but the DVWP will work the same, whether you are in SharePoint 2007, 2010, or 2013.

This DVWP will display the Document Library name in a header row and then the three most recently modified documents, whether or not they are in folders. I’m display the name of the document as a link, the Modified By user as a link to their info or User Profile (depending on license version), and the Modified date/time columns. If you’d like to show other columns you can add them into the ViewFields in the DataSource section and then into the XSL. (In a CrossList DVWP, you must explicitly request each column you’d like to use.) To adjust the number of documents displayed per Document Library, just change the value of the TopN param near the top of the XSL section.

<WebPartPages:DataFormWebPart runat="server" Description="" ListDisplayName="" PartOrder="1" HelpLink="" AllowRemove="True" IsVisible="True" AllowHide="True" UseSQLDataSourcePaging="True" ExportControlledProperties="True" IsIncludedFilter="" DataSourceID="" Title="Most Recent Documents" ViewFlag="8" NoDefaultStyle="TRUE" AllowConnect="True" FrameState="Normal" PageSize="-1" PartImageLarge="" AsyncRefresh="False" ExportMode="All" Dir="Default" DetailLink="" ShowWithSampleData="False" FrameType="Default" PartImageSmall="" IsIncluded="True" SuppressWebPartChrome="False" AllowEdit="True" EnableOriginalValue="False" AutoRefresh="False" AutoRefreshInterval="60" AllowMinimize="True" ViewContentTypeId="" InitialAsyncDataFetch="False" MissingAssembly="Cannot import this Web Part." HelpMode="Modeless" ListUrl="" ID="g_2b53a84e_bf26_4583_af64_ac20e428b458" ConnectionID="00000000-0000-0000-0000-000000000000" AllowZoneChange="True" ManualRefresh="False" __MarkupType="vsattributemarkup" __WebPartId="{D2B80E07-81CE-48C5-83A1-D124096DC364}" __AllowXSLTEditing="true" WebPart="true" Height="" Width="">
  <ParameterBinding Name="URL" Location="ServerVariable(URL)" DefaultValue=""/>
<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
  <xsl:output method="html" indent="no"/>
  <xsl:param name="URL"/>
  <xsl:param name="TopN">3</xsl:param>

  <xsl:template match="/" xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:SharePoint="Microsoft.SharePoint.WebControls">
    <xsl:call-template name="dvt_1"/>

  <xsl:template name="dvt_1">
    <xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>
    <table border="0" width="100%" cellpadding="2" cellspacing="0">
      <tr valign="top">
        <th class="ms-vh" nowrap="nowrap">Name</th>
        <th class="ms-vh" nowrap="nowrap">Modified By</th>
        <th class="ms-vh" nowrap="nowrap">Modified</th>
      <xsl:call-template name="dvt_1.body">
        <xsl:with-param name="Rows" select="$Rows"/>

  <xsl:template name="dvt_1.body">
    <xsl:param name="Rows"/>
    <xsl:for-each select="$Rows">
      <xsl:variable name="NewList" select="ddwrt:NameChanged(string(@ListProperty.Title), 0)"/>
      <xsl:if test="string-length($NewList) &gt; 0">
          <td class="ms-vb" style="background-color:#cfcfcf;" colspan="99">
            <a style="color:#990202;" href="/{substring-after(@FileDirRef, ';#')}"><xsl:value-of select="@ListProperty.Title" /></a>
        <xsl:call-template name="dvt_1.body2">
          <xsl:with-param name="Rows" select="$Rows[@ListProperty.Title = current()/@ListProperty.Title]"/>

  <xsl:template name="dvt_1.body2">
    <xsl:param name="Rows"/>
    <xsl:for-each select="$Rows">
      <xsl:sort select="ddwrt:FormatDateTime(string(@Modified), 1033, 'yyyyMMdd HHmmss')" order="descending"/>
      <xsl:if test="position() &lt;= $TopN">
        <xsl:call-template name="dvt_1.rowview" />

  <xsl:template name="dvt_1.rowview">
      <xsl:if test="position() mod 2 = 1">
        <xsl:attribute name="class">ms-alternating</xsl:attribute>
      <td class="ms-vb">
        <a href="/{substring-after(@FileDirRef, ';#')}/Forms/DispForm.aspx?ID={@ID}&amp;Source={$URL}"><xsl:value-of select="substring-after(@FileLeafRef, ';#')" /></a>
      <td class="ms-vb">
        <a href="/_layouts/userdisp.aspx?ID={substring-before(@Editor, ';#')}"><xsl:value-of select="substring-after(@Editor, ';#')"/></a>
      <td class="ms-vb">
        <xsl:value-of select="ddwrt:FormatDate(string(@Modified), 1033, 5)"/>

  <SharePoint:SPDataSource runat="server" DataSourceMode="CrossList" SelectCommand="&lt;View&gt;&lt;Lists ServerTemplate='101'&gt;&lt;/Lists&gt;<Query><Where><Eq><FieldRef Name='FSObjType' /><Value Type='int'>0</Value></Eq></Where><OrderBy><ListProperty Name='Title'/></OrderBy></Query>&lt;ViewFields&gt;&lt;ListProperty Name=&quot;Title&quot; /&gt;<FieldRef Name='FSObjType' />&lt;FieldRef Name=&quot;ID&quot;/&gt;&lt;FieldRef Name=&quot;Title&quot;/&gt;&lt;FieldRef Name=&quot;FileRef&quot;/&gt;&lt;FieldRef Name=&quot;FileDirRef&quot;/&gt;&lt;FieldRef Name=&quot;FileLeafRef&quot;/&gt;&lt;FieldRef Name=&quot;Editor&quot;/&gt;&lt;FieldRef Name=&quot;Modified&quot;/&gt;&lt;/ViewFields&gt;&lt;/ViewFields&gt;&lt;/View&gt;" UpdateCommand="" InsertCommand="" DeleteCommand="" UseInternalName="True" UseServerDataFormat="True" ID="dataformwebpart1">

Turn Off "Smart Quotes" in PowerPoint 2013

There are so many times when software is designed to do “smart” things for you. In many cases, those things aren’t as smart as they seem in actual practice.


Here’s an example of something that really gets in my way. Microsoft Office loves to convert “straight quotes” to “smart quotes”. If you’ve ever wondered why your single or double quote characters seem to curl up after you type the closing one, this is what is going on. It’s probably great if all you ever type is prose, but almost everything I type into Microsoft Word or PowerPoint has at least some code in it. When the straight quotes are converted into smart quotes, the characters are no longer valid code in almost every programming language.

Here’s how you can turn off this “smart” behavior in Microsoft PowerPoint 2013. (Sadly, with every new release of Office, this type of little setting seems to move to a new “undisclosed location”.)





Uncheck the “Straight quote” with “smart quotes” box.


SharePoint-Videos.com: JavaScript and jQuery for SharePoint 2013 Training – Online Class

SharePoint-Videos.comNext Thursday, May 23rd, 2013, I’ll be teaching a class for SharePoint-Videos.com called “JavaScript and jQuery for SharePoint 2013”. It’s an online class that is available to everyone, but it’s filling up fast.

This will be my first class fully focused on jQuery with SharePoint 2013, and I’ve had a lot of fun putting it together. SharePoint 2013 is more geared for great client-side programming opportunities than prior versions. Adding these development techniques to your toolkit can really help solve business requirements and improve the SharePoint user experience.

Here’s the registration link if you’d like to join us, and the class outline is below.

Class Outline

A jQuery Primer for SharePoint

  • Learn the important functionality of jQuery in SharePoint context
  • Find the parts of the page you need to work with using selectors
  • Traverse the Document Object Model (DOM) to act upon related elements
  • Manipulate elements to change their behavior, look, or structure
  • Bind to DOM events to add behavior and functionality
  • Use jQuery effects to add pizazz
  • Interact with the SharePoint server or other external services using AJAX
  • Improve the user experience and process by using deferred objects

SharePoint Client-Side Programming

  • Discuss the different client-side options: CSOM, REST, and SPServices (SOAP) and how to use each approach
  • Review examples of equivalent functionality using all three methods
  • Discover when each approach is best
  • Overview of the new App model
  • Find out when client-side programming makes sense and when it doesn’t

Richer UIs Using jQueryUI and Other Script-Based Plugins

  • Configurable dialogs
  • Improved calendaring
  • Drag and Drop
  • Autocomplete
  • Image Rotators

SharePoint 2013’s Search Continuous Crawl: An Enigma

I’m doing some work in SharePoint 2013 and we want to take advantage of as many out of the box capabilities as possible. We’re replacing an existing Intranet that has grown up in SharePoint from 2007 to 2010, and we’d like to rebuild with as little custom code as possible, since SharePoint 2013 now contains features that had to be custom built in the past.

The Intranet is build using a Publishing Portal and we want to use the Content Search Web Part (CSWP) to surface content in places like a home page rotator (the latest stories of certain Content Types within relative date ranges), in several “archive pages” (a list of the historical content, sorted by descending publishing date), and using search with the Search Results Web Part (SRWP) and the Refinement Web Part (RWP) in a page. The user stories and use cases here are not really all that complex: let’s show people the latest content of predetermined types regardless where it was created in the Publishing Portal.

The new Continuous Crawl capability in SharePoint 20103 sounds like it will fit the bill for us. We want the content that users see to be as fresh as possible. In fact, the TechNet article I link to below says that with Continuous Crawl “[t]he search results are very fresh, because the SharePoint content is crawled frequently to keep the search index up to date.” Sounds perfect, but we need to understand more about it.

We haven’t done much at all with the Search Service Application. We’ve got one Content Source, which is “Local SharePoint Sites”. In other words, it couldn’t be much simpler. Since search will underlie so much of the functionality, we need to understand exactly how the crawls are going to work and what sort of lag time we can expect users to have before they see content that is published. We can’t figure out exactly how Continuous Crawl works under the hood, so today I tried to do some experiments.

I set things to have no schedules to start out just to make things as fresh as possible, and just in case, I did a Full Crawl.



When the Full Crawl was done, the Content Source showed this status:


Next I clicked the Enable Continuous Crawls radio button. Note that when I did this, the Incremental Crawl schedule was automatically set to every 4 hours. This can be changed, but the incremental schedule cannot be set to “None” while the Enable Continuous Crawls radio button is selected.


The Content Source status changed to this:


In the log, it looks like an Incremental Crawl fired off when I saved that change at 11:34.


I waited for the Incremental Crawl to complete and published a new News Item at 11:37. The new content showed up in the CSWPs and the search results around 11:55. For some reason, a new Incremental Crawl started at 11:55 (21 minutes after the previous crawl).



I added some more new content at 11:58. That content showed up in the CSWP by 12:09. (I’m not sure exactly how many minutes it took to get there, but it was less than 12.) There’s nothing in the logs to indicate that a crawl occurred:


At 12:30, There was still nothing new in the logs:


All in all, this is still confusing to me. Continuous Crawl seems to be working, but at some underlying schedule which isn’t visible. There have been some suggestions that the Continuous Crawl schedule is set to every 15 minutes by default, and the evidence above seems to support that since the second piece of content showed up in 12 minutes, about 15 minutes after the last crawl that was visible in the logs.

There is some PowerShell you can use to get at properties of the Continuous Crawl, but it’s not totally clear what impact they have on the schedule.

$ssa = Get-SPEnterpriseSearchServiceApplication


Another thing that’s not clear is how many Continuous crawl threads might stack up if things get backed up. One person has suggested an unlitimited number and someone else told me there’s a maximum of 8 threads. Obviously, there’s not a clear understanding of this, either.

In researching things, there articles/posts seem useful:

This TechNet article is way too vague and only focuses on what buttons to push to turn Continuous Crawl on or off:

In my opinion, we need some much clearer documentation from Microsoft to explain how all of this holds together and I’m trying to track down the right people to see if I can help to make that happen. If you know who those people are an could give me an introduction, I’d appreciate it.

jQuery Library for SharePoint Web Services (SPServices) 2013.01 Released

Tonight I’ve released SPServices 2013.01. If you are using an earlier version of SPServices, I strongly suggest that you upgrade to this version, as you will see some performance improvements and there is some nice new functionality. Thanks to everyone who downloaded the beta and provided feedback.

jQuery Promises

By far the most exciting thing in this release is jQuery promises, or deferred objects. I’ve written about this several times already herehere and here. I won’t belabor the point too much, but if you’re interested in increasing the efficiency of your code and getting ready for the way you are likely to work with the REST Web Services in SharePoint 2013, you should get familiar with using promises.

Other Release Notes

There are other goodies in this release, and you can see the full list of enhancements and improvements on the download page. Note the link to the Issue Tracker items for this release. I’ve gotten a bit lazy with the release notes, so for this release the items in the Issue Tracker contain all of the details.