Using Unescaped CAML in a Data View Web Part (DWVP) in SharePoint Designer 2010

I’ve created more customized Data View Web Parts (DVWPs) than I could possibly count, but I still learn new stuff all the time. Tonight I was trying to get a DVWP to switch into DataSourceMode=”CrossList” and I accidentally noticed a nice little trick.

If you right-click on the DVWP and select Properties, a Tag Properties Task Pane will open up, probably in the bottom left or bottom right of your SharePoint Designer screen. If you click on the DataSource section, it’ll look something like this:

image

Note that the SelectCommand which I’ve highlighted is shown unescaped It seems that you can make edits there and SharePoint Designer will pass them into the DataSource section escaped, just as it must be.

I’ve used Notepad or XML escape Web pages or XML escaping apps to do this for years, and it turns out that SharePoint Designer would have done it for me all along. If that’s in some documentation somewhere, I challenge you to find it!

CAML Filter for Current Group Membership

My pal Christophe Humbert at PathToSharePoint.com forwarded me a question from one of his readers earlier today. I didn’t know the answer, but it intrigued me enough to track down the answer.

Something that a lot of people don’t realize is that every List View Web Part (LVWP) you use in your SharePoint pages contains the CAML required to render what it’s supposed to render. If you crack open the page with SharePoint Designer, you can find that CAML, copy it out, make it human readable (by changing the escaping to the real characters), and see what’s going on.

If you look at the CAML for the LVWP on the By My Groups view page in a Tasks list, you’ll see this Where clause:

<Where><Membership Type="CurrentUserGroups"><FieldRef Name="AssignedTo"/></Membership></Where>

or, formatted for humans:

<Where>
  <Membership Type="CurrentUserGroups">
    <FieldRef Name="AssignedTo"/>
  </Membership>
</Where>

If you look at the CAML schema, you can see the details for the options for Membership.  What this CAML Where clause is doing is filtering for items where the AssignedTo value exists in the the current user’s groups.  Sweet!

Frankly, this is a new one to me, but it makes sense.

Displaying Columns in a Crosslist DVWP

I’ve alluded to this in the past, but I had a client situation in the last few days that brought it top of mind again. One of the quirks of a Crosslist DVWP is that you *must* specify all columns you would like to display in the CAML for the Data Source. You can add any column in the XSL you want, but if they aren’t explicitly specified in the CAML, you will get blank results.

Here’s an example. Say you want to gather the latest announcements from across the Site Collection for display on the Home Page of your Intranet. You’re displaying the latest 5 announcements, but you realize that annoucements that are expired are still showing up. So, you add a filter to the row select, as below, and you’re not seeing what you’d expect.

<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row&#91;
    (ddwrt:FormatDateTime(string(ddwrt:Today()), 1033, 'yyyyMMdd') >=
    ddwrt:FormatDateTime(string(@Expires), 1033, 'yyyyMMdd')) or
    string-length(@Expires) = 0
  ]"/>

You’ll need to add an explicit FieldRef for the Expires column in your CAML, as below.  (I’ve added carriage returns and white space into the CAML above for readability, but you can’t have them in your DVWP.)

<SharePointWebControls:SPDataSource
  runat="server"
  DataSourceMode="CrossList"
  SelectCommand="
    <View>
      <Webs Scope='SiteCollection'></Webs>
      <Lists ServerTemplate='104'></Lists>
      <ViewFields>
        <FieldRef Name='ID'/>
        <FieldRef Name='Title'/>
        <FieldRef Name='Body'/>
        <FieldRef Name='FileDirRef'/>
        <FieldRef Name='Created'/>
        <FieldRef Name='Author'/>
        <FieldRef Name='Expires'/>
        <FieldRef Name='PermMask'/>
      </ViewFields>
    </View>"
  UseInternalName="true"
  ID="dataformwebpart5">
</SharePointWebControls:SPDataSource>

Once you add the FieldRef to the CAML, the Expires column values are available for use in your filter.

Keep in mind that you need to be careful what you add into your <Viewfields> section. If you add a FieldRef for a column which doesn’t occur in *all* of the items which you want to retrieve, you will, in effect, be adding a filter to the CAML. Only items which have all of the columns specified in the FieldRefs will be returned.

Project and List Properties Available from CAML

When you are building a DVWP in SharePoint, there are some project (Web site) and list properties that are available to you directly from CAML that aren’t well-documented, which you can use if you request them directly.  For instance, if you add the following to your CAML <ListProperty Name=”Title” /><ProjectProperty Name=”Title” />, the titles of the project and list are available to you:

<xsl:value-of select=”@ListProperty.Title” />
<xsl:value-of select=”@ProjectProperty.Title” />

These properties are especially useful when you build CrossList DVWPs in order to build up links to items and to display information about them on the page.

Here’s an actual example from a project I worked on:

&lt;View&gt;&lt;Webs Scope="SiteCollection"&gt;&lt;/Webs&gt;&lt;Lists ServerTemplate="104"&gt;&lt;/Lists&gt;&lt;Query/&gt;&lt;ViewFields&gt;&lt;ProjectProperty Name="Title"/&gt;&lt;FieldRef Name="ID"/&gt;&lt;FieldRef Name="Title"/&gt;&lt;FieldRef Name="Body"/&gt;&lt;FieldRef Name="FileDirRef"/&gt;&lt;FieldRef Name="Created"/&gt;&lt;FieldRef Name="Author"/&gt;&lt;FieldRef Name="Expires"/&gt;&lt;FieldRef Name="PermMask"/&gt;&lt;FieldRef Name="ShowOnRootPage"/&gt;&lt;/ViewFields&gt;&lt;/View&gt;

and again in “English”:

<View>
  <Webs Scope="SiteCollection"></Webs>
  <Lists ServerTemplate="104"></Lists>
  <Query/>
  <ViewFields>
    <ProjectProperty Name="Title"/>
    <FieldRef Name="ID"/>
    <FieldRef Name="Title"/>
    <FieldRef Name="Body"/>
    <FieldRef Name="FileDirRef"/>
    <FieldRef Name="Created"/>
    <FieldRef Name="Author"/>
    <FieldRef Name="Expires"/>
    <FieldRef Name="PermMask"/>
    <FieldRef Name="ShowOnRootPage"/>
  </ViewFields>
</View>

ProjectProperty.Property Value
A string that contains the name of a project property listed in the following table.

Name Value
BlogCategoryTitle Category of the current post item.
BlogPostTitle Title of the current post item.
Description Description of the current Web site.
RecycleBinEnabled 1 if the recycle bin is enabled; otherwise, 0.
SiteOwnerName User name of the owner for the current site collection.
SiteUrl Full URL of the current site collection.
Title Title of the current Web site.
Url Full URL of the current Web site.

See ProjectProperty.Property Property for the original MSDN article.

ListProperty.Property Value
A string that contains the name of a property listed in the following table.

Name Value
Created Date and time the list was created.
DefaultViewUrl Server-relative URL of the default list view.
Description Description of the list.
EnableSyndication true if RSS syndication is enabled for the list; otherwise, false.
ItemCount Number of items in the list.
LinkTitle Title linked to list.
MajorVersionLimit For a document library that uses version control with major versions only, maximum number of major versions allowed for items.
MajorWithMinorVersionsLimit For a document library that uses version control with both major and minor versions, maximum number of major versions allowed for items.
RelativeFolderPath Site-relative URL for the list.
Title Title of the list.
ViewSelector View selector with links to views for the list.

See ListProperty.Property Property for the original MSDN article.