Deploying/provisioning difficult web parts (like XsltListViewWebPart)




Deploying the XsltListViewWebPart to a page as part of a packaged solution can be a challenge (as well as some other web parts). When these web parts are exported they refer to the underlying list or library via its GUID rather than by URL or name. This means that that the web part cannot be imported using this same XML to another site as it will fail to find a list with that GUID.

As Microsoft’s guidance is now to avoid using the server-side object model, the previously most common way to resolve this issue is no longer available. Web parts could be provisioned by JSOM code on a page however that really feels messy and there some declarative alternatives.

SharePoint-2013-export-webpart

Replacing the AllUsersWebPart element with the View element

Specifically for provisioning an XsltListViewWebPart, rather than using the AllUsersWebPart element to provision a web part to page you can use a View element instead. The view element allows you to specific a list via URL, which when omitting a list reference in the child web part element, will be used to identify the list or library. This is my recommended approach. See here for the View element schema definition.

<View WebPartZoneID="wpzHeader" WebPartOrder="0" List="Lists/PromotedLinks" DefaultView="FALSE" BaseViewID="1" Hidden="TRUE">
 <![CDATA[
  <webParts>
   <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    <metaData>
     <type name="Microsoft.SharePoint.WebPartPages.XsltListViewWebPart,Microsoft.SharePoint,Version=15.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" />
     <importErrorMessage>Cannot import this Web Part.</importErrorMessage>
    </metaData>
    <data>
     <properties>
      <property name="AllowConnect" type="bool">True</property>
      <property name="ChromeType" type="chrometype">None</property>
      <property name="Title" type="string">Promoted Links</property>
     </properties>
    </data>
   </webPart>
  </webParts>
 ]]>
</View>

 

Using the listId token for document libraries

There is a token that can be used to replace the library GUIDs in the web part XML. I say library specifically as I can’t seem to get this approach to work with lists. The properties that need to be replaced with token are as follows (in this example we are referencing the ‘Documents’ library):

<property name="ListName" type="string">{$ListId:Documents;}</property>

<property name="ListId" type="System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">$ListId:Documents;</property>

An example of the full XML using this approach can be found here.

This method can be used for other web parts as well such as specifying a specific list when deploying a ContentQueryWebPart.

Using BinarySerializedWebPart for lists or libaries

The other option is a very static and rather awkward approach to solving this issue – but at least it works. The BinarySerializedWebPart allows any web part to be imported in a binary format and provides a mechanism for mapping GUID to URL. The major downside is that if you want to make a minor change it will require you to re-create the binary representation of the web part.

In order to find this XML you will need to configure a web part as desired on a site that has never had publishing features enabled and then import the site as a site template (the publishing features disable the export site template functionality and although you can get around this you can get very strange side-effects, so I recommend avoiding doing so. e.g. I once found that all my Script Editor web parts were deleted from my site after performing the operation on site with publishing features enabled). By downloading and renaming the site template package as a .cab you will be able to find an Elements.xml that contains all the xml for deploying web parts, including yours as BinarySerializedWebPart if it can’t be otherwise imported.

For more information on this see here.

Good luck!




6 thoughts on “Deploying/provisioning difficult web parts (like XsltListViewWebPart)”

  1. This is excellent and has solved a major problem of mine, thank you for posting.

    I did try your second example, using the XML provided that replaces list names with the ListId:Documents syntax, but it doesn’t seem to work.

    In which node of the element are you placing the content? Does it need to be under , or ?

  2. Hello! Thank you very much for this post!
    I tried your code, and as you stated, {$ListId:Documents;} only works with Document Libraries.

    After googling for a while I discovered that adding “Lists/” before the list name does the trick for a non-document library list

    {$ListId:Lists/SomeList;}

    I hope someone can benefit from this!

Leave a Reply

Your email address will not be published.