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.
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.
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!
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 ?
Meant to say does it need to be under the List node, or AllUsersWebPart node?
The token can be used in property elements under the AllUsersWebPart element, not under the View element to my knowledge.
Cheers, Paul
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!
Thanks for your input Nicole
At last something useful! Many thanks!