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="">
<ParameterBindings>
  <ParameterBinding Name="URL" Location="ServerVariable(URL)" DefaultValue=""/>
</ParameterBindings>
<Xsl>
<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>

  <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>
      </tr>
      <xsl:call-template name="dvt_1.body">
        <xsl:with-param name="Rows" select="$Rows"/>
      </xsl:call-template>
    </table>
  </xsl:template>

  <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">
        <tr>
          <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>
          </td>
        </tr>
        <xsl:call-template name="dvt_1.body2">
          <xsl:with-param name="Rows" select="$Rows[@ListProperty.Title = current()/@ListProperty.Title]"/>
        </xsl:call-template>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

  <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:if>
    </xsl:for-each>
  </xsl:template>

  <xsl:template name="dvt_1.rowview">
    <tr>
      <xsl:if test="position() mod 2 = 1">
        <xsl:attribute name="class">ms-alternating</xsl:attribute>
      </xsl:if>
      <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>
      <td class="ms-vb">
        <a href="/_layouts/userdisp.aspx?ID={substring-before(@Editor, ';#')}"><xsl:value-of select="substring-after(@Editor, ';#')"/></a>
      </td>
      <td class="ms-vb">
        <xsl:value-of select="ddwrt:FormatDate(string(@Modified), 1033, 5)"/>
      </td>
    </tr>
  </xsl:template>

</xsl:stylesheet></Xsl>
<DataSources>
  <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">
  </SharePoint:SPDataSource>
</DataSources>
</WebPartPages:DataFormWebPart>

Displaying Blog Posts in Different Sites in SharePoint 2010

SharePoint blogs are no one’s favorite. There is just enough functionality there to make them useful, but not enough functionality to make them useful enough. On top of that, blogs are sites, not lists. That seems counterintuitive on one level – isn’t it just a list of posts? – but it makes sense on other levels. There are actually three important lists in a blog site: Posts, Comments, and Categories. There are two other lists as well – Photos and Links – but I rarely see them used in blog sites.

Because there are multiple lists and the site itself has some unique functionality, it actually does make sense that it is a separate site that uses a unique Site Template.

image

One problem with this is that it is then difficult to display blog posts in other sites. Sure, you can use the Content Query Web Part (CQWP) to do it, but the display options out of the box are pretty abysmal. Other options are an RSS Web Part or even search.

However, if you want to display blog posts elsewhere with any sort of fidelity, you will probably want to use a Data View Web Part (DVWP).

In this post, I’ll show you the quick steps to make that work, without much beautification. I’ll assume you already have your blog site up and running. The basic idea is that we will created a DVWP in the blog site, make a few manual edits to it, and then copy it into a page in another site. One note: I’m a bit more of a hack, so I would shortcut past a few of these steps. I’m trying to make it very straightforward and involving as little manual coding as possible.

Step 1: Create the DVWP

Open the blog site with SharePoint Designer. The home page of the blog site is default.aspx, so make a copy of that page and edit it in Advanced Mode. You’ll want to use the Design View or Split View for this. Enjoy them now, as they are gone in SharePoint Designer 2013!

On the ribbon, choose Insert / Data View / Empty Data View. If you choose a list at this point, you’ll end up with an XLV Web Part instead, which won’t work for our purposes because they cannot pull information from other sites – only DVWPs are good for this. Click on the ‘Click here to select a data source’ link and choose the Posts list.

image

Add whatever columns you’d like to display in your DVWP as a Multiple Item View. For this example, I’ve chosen Title, Created, and Created By.

image

Right click on the Title column and choose Format item as / Hyperlink to / Display form. The link will have a hard-coded URL, which is bad, but remember we’re just doing the basics here. It’ll work to get you to the actual post for the other site.

image

Make whatever other changes you’d like in the DVWP (Paging, Item Limits, column formatting, etc.), save the page, and test it in the browser. You should see your DVWP where you inserted it in the page. Mine is right up top:

image

Step 2: Modify the DVWP’s DataSource

Once you have the DVWP showing what you’d like to see, we have a couple more things we need to do to the DVWP to make it work in the other site.

Somewhere in the code for the DVWP, you’ll see the DataSources section. It’ll look something like this, depending on how you’ve formatted the DVWP:

<DataSources>
  <SharePoint:SPDataSource runat="server" DataSourceMode="List" UseInternalName="true" UseServerDataFormat="true" selectcommand="&lt;View&gt;&lt;/View&gt;" id="dataformwebpart1">
    <SelectParameters>
      <WebPartPages:DataFormParameter Name="ListID" ParameterKey="ListID" PropertyName="ParameterValues" DefaultValue="{AEC1CA2C-EFA6-4218-A742-5939F94E0DDE}"/>
      <asp:Parameter Name="StartRowIndex" DefaultValue="0"/>
      <asp:Parameter Name="nextpagedata" DefaultValue="0"/>
      <asp:Parameter Name="MaximumRows" DefaultValue="10"/>
    </SelectParameters>
    <DeleteParameters>
      <WebPartPages:DataFormParameter Name="ListID" ParameterKey="ListID" PropertyName="ParameterValues" DefaultValue="{AEC1CA2C-EFA6-4218-A742-5939F94E0DDE}"/>
    </DeleteParameters>
    <UpdateParameters>
      <WebPartPages:DataFormParameter Name="ListID" ParameterKey="ListID" PropertyName="ParameterValues" DefaultValue="{AEC1CA2C-EFA6-4218-A742-5939F94E0DDE}"/>
    </UpdateParameters>
    <InsertParameters>
      <WebPartPages:DataFormParameter Name="ListID" ParameterKey="ListID" PropertyName="ParameterValues" DefaultValue="{AEC1CA2C-EFA6-4218-A742-5939F94E0DDE}"/>
    </InsertParameters>
  </SharePoint:SPDataSource>
</DataSources>

We need to add the WebURL parameter, as I describe in my older post Using a DataSource in a Data View Web Part (DVWP) in a Different Site in SharePoint Designer 2010. You should use the relative path to the blog site as the value. In my case, it’s “/sites/demos/blog”.

The end result should be something like this:

<DataSources>
  <SharePoint:SPDataSource runat="server" DataSourceMode="List" UseInternalName="true" UseServerDataFormat="true" selectcommand="&lt;View&gt;&lt;/View&gt;" id="dataformwebpart1">
    <SelectParameters>
      <WebPartPages:DataFormParameter Name="ListName" ParameterKey="ListName" PropertyName="ParameterValues" DefaultValue="Posts"/>
      <WebPartPages:DataFormParameter Name="WebURL" ParameterKey="WebURL" PropertyName="ParameterValues" DefaultValue="/sites/demos/blog/"/>
      <asp:Parameter Name="StartRowIndex" DefaultValue="0"/>
      <asp:Parameter Name="nextpagedata" DefaultValue="0"/>
      <asp:Parameter Name="MaximumRows" DefaultValue="10"/>
    </SelectParameters>
  </SharePoint:SPDataSource>
</DataSources>

Note that you can delete the DeleteParameters, UpdateParameters, and InsertParameters sections because we’re only displaying data in the DWP (SelectParameters are used for that).

You’ll also need to remove the listname attribute in the DVWP header, which will look something like this:

listname="{AEC1CA2C-EFA6-4218-A742-5939F94E0DDE}"

Save the page again and test it in the browser. Nothing should have changed and the DVWP should be working just fine.

Step 3: Export the DVWP

I usually just copy and paste the DVWP code from one SharePoint Designer window to the other, but here we’re going to use the Export / Import mechanisms instead.

You should already have the page open, so simply click in the upper right corner of the DVWP and choose Export.

image

In IE(, I get this prompt

image

and I just choose to save the Posts.webpart file somewhere I’ll be able to find it again.

Step 4: Import the DVWP into the Other Site

Now we’ll add the DVWP to the other site. Navigate to the page where you’d like to display the DVWP, and put the page into Edit Mode. Position the cursor where you’d like the DVWP and on the ribbon, choose Insert / Web Part.

I’m going to add mine right under the intro text on a Team Site. You’ll see that there’s an option to Upload a Web Part, which I’ve highlighted below. Click on that, browse the the Posts.webpart file you saved in Step 3, and then click upload.

image

You’ll have to reply to a prompt to save the page and then you’ll be right back at the page without your DVWP. What? Yeah, some bad UI here. But you should see a new Category called Imported Web Parts, and your Posts Web Part should be listed there. (I uploaded twice by accident in the screen grab below, but you get the idea.) You can insert the Posts DVWP wherever you’d like in the page.

image

As I mentioned, you can also copy and paste the DVWP code from one page to another, depending on your comfort level.

Next Steps

Now your users can read blog info wherever you’d like to display it, without going to the blog site itself. If you’d like to, you can format the posts anyway you’d like in the DVWP, of course. To keep things simple, I’m just displaying some basic info in a list-oriented view. You could mimic the display from the blog site or anything else that tickles your fancy.

Is Client Side Scripting a Good Way to Access SharePoint Data?

People reach out to me all the time to ask my advice on how to accomplish certain things with SharePoint. Sometimes I can help, and sometimes their questions are way beyond me. One of the benefits of being reasonably well known in the SharePoint space is that people tend to come to me with questions that are up my alley.

When the questions aren’t something I can handle, I usually suggest that they use one of the public forums out there. My favorite is SharePoint StackExchange and in a distant second, the MSDN Forums for SharePoint.

Other times, either due to how they found me or based on the content of their questions, things stay in an email exchange.

The other day, my friend and colleague Christina Wheeler (@cwheeler76) passed along some questions from someone she knew [I’ve edited each part of the exchange a little for clarity and anonymity]:

I was wondering if you have a good resource within your network that might have published a blog about the different ways to access Sharepoint list data (client side scripting using something like SPServices or server side scripting using a deployable web part). Also, are there any other ways to accomplish this? I know the data view web part is another method, but it has its limitations.

A good example would be wanting to combine data from a SharePoint list and an external list and display both back to the browser window. I thought SPServices would be an excellent alternative to the data view web part, because it wouldn’t require taking the server down to deploy or redeploy. However, there are concerns coming from my team that client side is not as fast, secure etc. So I am just looking to see if there are any resources out there that have addressed this as it relates directly to Sharepoint.

Well, she certainly arrived in the right place with those questions. Since SPServices is mine, I can certainly answer any questions about it better than most people. The first thing I did was refer her to the post that Mark Rackley (@MrAckley) and I wrote together called When to Choose SPServices vs. the Client Side Object Model (CSOM). That post has gotten a lot of reads and Mark and I still think it covers the topic pretty well.

That prompted the next set of questions:

Thank you so very much for pointing me to all this valuable information! […] mentioned the SPServices […], and from then, I was hooked. Honestly, it was the number one thing I took away […] because of its potential to get around some Sharepoint limitations. To give you an example, we have a […] calendar that is managed under the IT site for the Sharepoint intranet. We like to display a summary of the daily or upcoming downtime to appear on the home page. The only way to display this data from another sub site (before) was with an RSS feed. The problem with the RSS feed is when we get into reoccurring events on the Sharepoint calendar. Now, I abandoned the RSS feed in favor of SPServices and it works beautifully.

My problem comes in with trying to get everyone on board that client scripting is okay to use for returning SharePoint list data. This argument is a perfect example. I am familiar with both client side scripting (javascript, xslt, jquery) and server side scripting with C#, but I don’t claim to be an expert. The argument that has been presented to me is that server side scripting is preferred because:

1.) It’s more secure

2.) It’s browser independent

3.) It’s better from a performance perspective

I tend to disagree that server side scripting is always the better answer for Sharepoint solutions. For one, we are not talking about writing an ERP payroll system where I plan to return thousands and thousands of records, so the amount of data I plan to return from a SharePoint list is minimal enough that I don’t think performance is a concern. For browser independence, that’s why I use jquery. And I don’t really know the answer about security. I think it comes down to what I want to do with the javascript. I am talking about using js to return a Sharepoint list. In this scenario, there is no increased threat of any kind by choosing to use client side javascript over a custom deployable web part written in C#. The case I am trying to argue is that using client side scripting to access a Sharepoint list is now possible, and in some cases, more desirable because it is easier to test, deploy, update and would not require any server downtime. I would just like to know your thoughts on this, or perhaps any resources…another blog or white paper you wrote that touches on best practices for when to use client side scripting vs server side development? Please bear with me because I have only been using Sharepoint for 6 months. Are there any other options to displaying Sharepoint list data other than using client side scripting like SPServices or CSOM, or to write an ASP.net page or deploy a custom web part that uses the Sharepoint Object model reference? I’m sure this is such an obvious answer that I have never really understood the answer to!

We plan to debate this issue tomorrow and I am just trying to make sure I understand the concerns/risks about coding for Sharepoint, specifically. There are lots of resources that touch on when to use client side scripting vs server side coding, but I think it’s not so black and white when it comes to working with Sharepoint.

And my reply was this:

You’re spot on in your thinking. This is a classic “it depends” scenario, of course. A good architect looks at all of the possible tools to solve the problem and decides where and when to use each one. Client side scripting is an excellent option for some things and just downright a bad idea for others.

The security argument is moot. The Web Services fully respect the permission model. If the user can’t access something through the UI, they can’t through the Web Services, either. QED. In a way, it’s even *more* secure than server side code since it’s impossible to elevate permissions, which many developers do as a common practice whether it’s needed or not.

Here are some more posts which may be helpful [each here on my blog]:

http://sympmarc.com/2011/05/27/elevating-permissions-with-sharepoints-web-services/

http://sympmarc.com/2011/06/06/using-script-to-hide-content-not-always-a-good-idea/

http://sympmarc.com/2011/05/18/sharepoint-myths-part-2/

Finally, the best argument that you can make is that Microsoft is going to a distributed, client side development model in SharePoint 2013, relying on (you guessed it) JavaScript and jQuery much of the time. If they are baking it into the product set by expanding their version of the API (versus mine with SPServices) how can someone argue that client side development is flat out a bad idea?

I don’t know if this little exchange will be useful for anyone else or not. However, it seems like every time I answer questions like there, it helps me to crystalize my thinking a little more. If it’s helpful to others, great. Otherwise, at least I had a little fun writing it up.

Calculate Days between Two SharePoint List Dates in XSL Using ddwrt:DateTimeTick

There was an interesting question over in the MSDN Forums the other day that I struggled to answer. It was a headscratcher, so I had to figure it out. In the thread, emfuentes27 wanted to know why s/he saw different results in SharePoint Designer than in the browser when using this formula:

<xsl:value-of select="number(ddwrt:DateTimeTick(ddwrt:GenDisplayName(string(@Due_Date))))- number(ddwrt:DateTimeTick(ddwrt:GenDisplayName(string($Today))))" />

Not only had I never seen the ddwrt:DateTimeTick function (no documentation on that is available anywhere at all that I can find), but the numbers just didn’t make sense.

[important]The ddwrt namespace functions are incredibly valuable, but they are simply not documented by Microsoft anywhere. There is a single article by Serge van den Oever (@svdoever) from the SharePoint 2003 days which explains it (very well), but that’s really it.[/important]

The ddwrt:DateTimeTick isn’t documented there and I’d never seen it in the wild. At least now I know about it.

To determine the days between two dates in the past, I’ve always used date arithmetic XSL templates, as I explain in my post Date Arithmetic in SharePoint DVWPs. The ddwrt:DateTimeTick function turns out to be a lot easier to use, but as I said, the numbers just didn’t make sense. They didn’t make sense, that is, until I went back to a little arithmetic.

It seems that the values in the browser were off from the ones in SPD (I tested this in WSS 3.0 because I had that VM open) by a factor of 864000000000. Trying to figure out the significance of that, I realized that it’s the number of seconds in a day times 1 million:

864000000000 = 60 * 60 * 24 * 1000000

60 * 60 * 24 = the number of seconds in a day.

Wolfram Alpha helps with this. Try going there and typing in 86400 seconds.

Who knows why this is the case, but this equation will give you the right answer in a browser (it will be wrong in SPD), which is what you are really after in the first place:

<xsl:value-of select="(number(ddwrt:DateTimeTick(ddwrt:GenDisplayName(string(@Lead_x0020_Date)))) - number(ddwrt:DateTimeTick(ddwrt:GenDisplayName(string(@Created))))) div 864000000000" />

The ddwrt:DateTimeTick function is a great tool for your XSL work in SharePoint. It returns the number of “ticks” since Dec 30, 1899 in SharePoint Designer. That’s an odd date to use as the base, but you can test it by adding this to your XSL:

1899-12-30::<xsl:value-of select="ddwrt:DateTimeTick(ddwrt:GenDisplayName(string('0001-01-01')))" /><br/>
1899-12-31::<xsl:value-of select="ddwrt:DateTimeTick(ddwrt:GenDisplayName(string('0001-01-02')))" /><br/>
1900-01-01::<xsl:value-of select="ddwrt:DateTimeTick(ddwrt:GenDisplayName(string('0001-01-03')))" /><br/>

Even odder, the base date in the browser seems to be Jan 1, 0001. You don’t see that date bandied about too often. Go ahead; give it a go:

0001-01-01::<xsl:value-of select="ddwrt:DateTimeTick(ddwrt:GenDisplayName(string('0001-01-01'))) div 864000000000" /><br/>
0001-01-02::<xsl:value-of select="ddwrt:DateTimeTick(ddwrt:GenDisplayName(string('0001-01-02'))) div 864000000000" /><br/>
0001-01-03::<xsl:value-of select="ddwrt:DateTimeTick(ddwrt:GenDisplayName(string('0001-01-03'))) div 864000000000" /><br/>

This is yet another example where the rendering engine in SharePoint Designer doesn’t yield the same results as what the SharePoint server provides. Don’t expect something like this to be fixed any time soon, though, given Microsoft’s abandonment of the Design and Split View in SharePoint Designer 2013.

We don’t really care what the base date is for zero ticks, of course; we just want to be able to use the values to determine the difference in days between two “ticks”. As long as you use the million-day-seconds trick, all is well.

This post also appeared at NothingButSharePoint.com on 2013-01-09. Visit the post there to read additional comments.

SharePoint Designer 2013′s Missing Design View – It’s Official

Well, Keenan Newton did a post on the Microsoft SharePoint Team Blog entitle Changes to the Design View in SharePoint Designer 2013 yesterday that makes it official: the Design View in SharePoint Designer 2013 is not just missing, it’s not coming back. I’m reproducing Keenan’s post below, but you should also read it in situ, as the comments are already piling up, and they aren’t positive.

Hi, I’m Keenan Newton, a senior product marketing manager on the SharePoint team.

We’re making some changes to the Design View in SharePoint Designer 2013, and I wanted to talk about the reasoning behind the changes.

With SharePoint Server 2013 embracing new web standards for client side rendering of pages such as JavaScript, JSON, and OData, there is no longer a need to support a visual web page editor within SharePoint Designer. With that in mind, we removed the ability to visually edit pages in SharePoint Designer 2013 because its page editor is designed to only understand the unique features of a SharePoint web page. With our support of new web standards, any web page designer can now be used for editing web pages in SharePoint Server 2013. This includes form customization, conditional formatting of page content, layout, theming and branding. To simplify the process of integrating customized SharePoint pages, SharePoint Server 2013 includes a new feature called the SharePoint Design Manager. This feature enables a web designer to export a web page from SharePoint, customize it, and then import it back into SharePoint, all right from the SharePoint site.

SharePoint Designer 2013 will continue to support site, workflow, list, library, and external data customization and configuration. However, we will look for opportunities to leverage SharePoint itself as the primary tool for customization and configuration tasks.

I’m not going to be politic about it: this is going to hurt Microsoft and it’s a horrible decision. The things you may be able to use Design Manager to do and workflows are not what the majority of people use SharePoint Designer for. Code View will do those same people virtually zero good, and there’s no replacement strategy.

Here are some of my specific beefs with the “official” stance that Keenan puts forth.

…we removed the ability to visually edit pages in SharePoint Designer 2013 because its page editor is designed to only understand the unique features of a SharePoint web page.

Exactly! The reason we choose to use SharePoint Designer is *because* it understands “the unique features of a SharePoint web page”. Nothing else does. For better or worse, SharePoint 2013’s forms, for example, are the same as they have been in 2007 and 2010, based on the List Form Web Part. No other editor knows what that is. SharePoint Designer does.

…any web page designer can now be used for editing web pages in SharePoint Server 2013.

This has always been the case, but who has decided to use Notepad or anything else in the past? We’ve always had the option to copy aspx page content out into some other editor to work on it, and that seems to be what Microsoft is recommending now. SharePoint Designer was and is the only IDE that understands SharePoint’s page structures, controls, and Data Sources. With any other tool, we have to know ourselves how to set up a Data Source in a DVWP or which controls to add to take advantage of SharePoint-specific functionality. In the newly neutered SharePoint Designer, many of the ribbon buttons actually serve no purpose anymore. Things like Conditional Formatting, DVWP formatting options, etc. don’t function unless we write our own code first. On top of that, there is no longer a surface where SharePoint Designer can show us errors in that code. Errors, cryptic or not, have always been shown in the Design (or Split) View. Now we will be flying blind.

To simplify the process of integrating customized SharePoint pages, SharePoint Server 2013 includes a new feature called the SharePoint Design Manager…

Maybe Microsoft believes that the Designer word in SharePoint Designer means that people only use it for design. As you and I know, design is only one small piece of how we use SharePoint Designer. Design Manager also is only useful if you want to apply a design via a master page or page layout to an entire Site Collection that has publishing features enabled. It doesn’t do us any good on individual pages where we want to make small customizations in the design or structure for single-location functionality.

All in all, I’m very disappointed in Microsoft’s decision on this one. As I’ve been telling people, I’ll be fine. As a consultant, I can keep working with SharePoint 2007 and 2010 for a long time and make a decent living at it. I can even learn to work in the Code View exclusively in SharePoint Designer 2013. I’m worried about all of the unsung heroes out there in SharePointland who have been using SharePoint Designer to build solutions that their organizations actually use, rather than what IT typically jams down their throats. Those of us who believe in user empowerment and citizen development have lost a battle this day.

[important]For another great slant on all of this, check out Michal Pisarek’s (@michalpisarek) great post from yesterday SharePoint 2013 Design View Changes and Change Management 101. In it, he makes some excellent points about how the change management around all of this has been abysmal.[/important]