I am a huge believer that before beginning any work on new functionality, an organization that has invested in SharePoint 2010 should always ask the question, “Does SharePoint give me a way to do this out of the box?”. Recently, a client requested to have the items in a site’s “Pages Library” displayed on the default page of the site in a list format. If you have ever used SharePoint, you know that every list or library created on a site has a corresponding list view web part that can be added to any web part page, and it will list all the items in the respective list or library by default. With that in mind, this seemed like an incredibly straightforward configuration effort that would only necessitate creating a custom view for the web part that adhered to the client’s requirements for the listing. However, while creating the custom view I unexpectedly encountered a little snag.

As a side note, in my opinion the only real limitation of the list view web part (XSLTListViewWebPart to be precise) is that it does not provide a great way to filter items based on the “Target Audiences” of the current user. Sure, you can create a view filtered for each “Target Audience”, and then add multiple audience targeted web part for each filtered view to a page, but that can be an exhaustive configuration effort that is not easy to maintain. Let us assume that the list on this specific site either did not intend to use “Target Audiences” to limit display in the web part, or it had custom permissions applied to limit access and remove specific pages from the view.

That little snag I referred to in the first paragraph of this blog was that the client wanted the “Title” field to link to the pages instead of the "Name" field. Now, if this list were any “item” based list (custom list, announcements, events…) I could have simply checked the box next to the field “Title Linked to Item” when modifying/creating the view. Unfortunately, this field is not available on any “document” based list. Instead, document based lists (libraries if you prefer), which includes “Pages”, link using the “Name” field. In our case, a specific name could very well be “Page-1.aspx”, which was not deemed appropriate for display in the listing.

After a few Google queries netted some overly complex solutions that required custom coding, I decided to open up SharePoint Designer (2010) to see what it could provide. I navigated to my custom view, and tried the “Show Link to Item” option that is available when selecting the little (>) icon next to the field in the view. While this option allowed the user to open the page, it opened it in a dialogue, which was not what they were looking for. Not to be disconcerted, I kept poking around designer, and suddenly remembered that the view was being displayed via an XSLTListViewWebPart.

And what do all XSLTListViewWebParts allow us to do? Apply XSL!

I will preface the rest of this blog by saying that by no means is this approach the user-friendliest or most architecturally astounding solution. However, I will say that it is a quick, effective approach at utilizing the functionality of the out of the box XSLTListViewWebPart (Pages, Documents, Images…) to display linked titles on document based list views.

A quick tip when using Designer to apply custom formatting to specific columns (in our case the title column) in a view:

  • Select the column you are interested in applying custom formatting (XSL) to
  • Click the (fX) formatting button, and without modifying any values click “OK”

Designer will then spit out a little XSL formatting block in the code behind for your column(s) that looks something like:

<span class="sc3"><span class="re1"><></span> <span class="re0">exclude-result-prefixes</span>=<span class="st0">"xsl msxsl ddwrt"</span> <span class="re0">version</span>=<span class="st0">"1.0"</span> <span class="re0">xmlns:__designer</span>=<span class="st0">"http://schemas.microsoft.com/WebParts/v2/DataView/designer"</span> <span class="re0">xmlns:asp</span>=<span class="st0">"http://schemas.microsoft.com/ASPNET/20"</span> <span class="re0">xmlns:d</span>=<span class="st0">"http://schemas.microsoft.com/sharepoint/dsp"</span> <span class="re0">xmlns:ddwrt</span>=<span class="st0">"http://schemas.microsoft.com/WebParts/v2/DataView/runtime"</span> <span class="re0">xmlns:ddwrt2</span>=<span class="st0">"urn:frontpage:internal"</span> <span class="re0">xmlns:msxsl</span>=<span class="st0">"urn:schemas-microsoft-com:xslt"</span> <span class="re0">xmlns:o</span>=<span class="st0">"urn:schemas-microsoft-com:office:office"</span> <span class="re0">xmlns:sharepoint</span>=<span class="st0">"Microsoft.SharePoint.WebControls"</span> <span class="re0">xmlns:x</span>=<span class="st0">"http://www.w3.org/2001/XMLSchema"</span> <span class="re0">xmlns:xsl</span>=<span class="st0">"http://www.w3.org/1999/XSL/Transform"</span><span class="re2">></span></span> <span class="sc3"><span class="re1"><></span> <span class="re0">href</span>=<span class="st0">"/_layouts/xsl/main.xsl"</span><span class="re2">></span></span> <span class="sc3"><span class="re1"><></span> <span class="re0">href</span>=<span class="st0">"/_layouts/xsl/internal.xsl"</span><span class="re2">></span></span> <span class="sc3"><span class="re1"><></span> <span class="re0">name</span>=<span class="st0">"AllRows"</span> <span class="re0">select</span>=<span class="st0">"/dsQueryResponse/Rows/Row[$EntityName = '' or (position() >= $FirstRow and position() <= $LastRow)]"</span><span class="re2">></span></span> <span class="sc3"><span class="re1"><></span> <span class="re0">name</span>=<span class="st0">"dvt_apos"</span><span class="re2">></span></span>'<span class="sc3"><span class="re1"><span class="re2">></span></span></span> <span class="sc3"><span class="re1"><></span> <span class="re0">ddwrt:dvt_mode</span>=<span class="st0">"body"</span> <span class="re0">ddwrt:ghost</span>=<span class="st0">""</span> <span class="re0">match</span>=<span class="st0">"FieldRef[@Name='Title']"</span> <span class="re0">mode</span>=<span class="st0">"Text_body"</span> <span class="re0">name</span>=<span class="st0">"FieldRef_Text_body.Title"</span> <span class="re0">xmlns:ddwrt2</span>=<span class="st0">"urn:frontpage:internal"</span><span class="re2">></span></span> <span class="sc3"><span class="re1"><></span> <span class="re0">name</span>=<span class="st0">"thisNode"</span> <span class="re0">select</span>=<span class="st0">"."</span><span class="re2">></span></span> <span class="sc3"><span class="re1"><><span class="re2">></span></span></span> <span class="sc3"><span class="re1"><></span> <span class="re0">test</span>=<span class="st0">"@AutoHyperLink='TRUE'"</span><span class="re2">></span></span> <span class="sc3"><span class="re1"><></span> <span class="re0">href</span>=<span class="st0">"{$thisNode/@FileLeafRef}"</span><span class="re2">></span></span> <span class="sc3"><span class="re1"><></span> <span class="re0">select</span>=<span class="st0">"$thisNode/@*[name()=current()/@Name]"</span><span class="re2">></span></span> <span class="sc3"><span class="re1"><span class="re2">></span></span><span class="re1"><span class="re2">></span></span></span> <span class="sc3"><span class="re1"><span class="re2">></span></span></span> <span class="sc3"><span class="re1"><><span class="re2">></span></span></span> <span class="sc3"><span class="re1"><></span> <span class="re0">href</span>=<span class="st0">"{$thisNode/@FileLeafRef}"</span><span class="re2">></span></span> <span class="sc3"><span class="re1"><></span> <span class="re0">select</span>=<span class="st0">"$thisNode/@*[name()=current()/@Name]"</span><span class="re2">></span></span> <span class="sc3"><span class="re1"><span class="re2">></span></span><span class="re1"><span class="re2">></span></span></span> <span class="sc3"><span class="re1"><span class="re2">></span></span></span> <span class="sc3"><span class="re1"><span class="re2">></span></span></span> <span class="sc3"><span class="re1"><span class="re2">></span></span><span class="re1"><span class="re2">></span></span></span> <span class="sc3"><span class="re1"><span class="re2">></span></span><span class="re1"><span class="re2">></span></span><span class="re1"><span class="re2">></span></span><span class="re1"><span class="re2">></span></span></span>

The text, "..." in the code block above is all I had to add in order to make the title link to the actual pages themselves, everything else was output by SharePoint Designer. You can also create the link using the “FileRef” field, but it is not necessary when linking to items on the current site.

Next, I copied the block of SharePoint Designer generated code with my small tweaks into a separate .xsl file, and uploaded the file to a folder in the site’s “Style Library.” Then, I went to the SharePoint site and added the out of box “Pages” web part. I edited the web part, selected my custom view, and then modified the XSL Link property in the “Miscellaneous” section to point to my XSL file. After clicking OK, all of the titles were updated to be links. Unfortunately, they all linked to the same file. After doing a bit of research and testing, I found that I had to add the “Type” field to my view. After adding the “Type” field, all of the links were then updated to point to the appropriate pages. I am not certain why I had to add this field, but it appears that the view needs to have the “FileLeafRef” available for the links to work, and both the “Type” and “Name” fields provide this to the view. Also, note that this code block expects the title field to be on the view, so don’t apply this specific XSL if your view does not have title (or build additional logic into the XSL to handle that situation).

The obvious downsides to this approach are that the user has to provide the XSL link whenever they want this formatting applied, the view itself on the system page does not display the linked titles (you have to edit the web part on the system page and provide the XSL link to display linked titles), and you have to add the “Type” field to the view to get the functionality to work. That said I definitely see where it may be worthwhile to perform additional development to add something like a “Title linked to item” field to the create/modify view interface if this is functionality that is needed throughout a site collection. However, this solution can quickly be applied to any site collection, works with any list view web part that needs to link the title to a specific document type item, and does not require any real coding effort outside the SharePoint Designer auto-generated block (with slight tweaks). Finally, I feel that this solution is very much in line with my philosophy of utilizing SharePoint out of box functionality to meet an organization’s needs when possible.