Programatically Organizing Web Parts in a Gallery
The other day we were given the challenge of organizing web parts for "my site" site collections.
The interesting thing about "my sites" is that they are created on the fly, which rules out the option of manually organizing the web parts.
We could deploy a feature that adds web parts to the gallery by provisioning the *.dwp and *.webpart files. However, there doesn't seem to be an easy way to delete existing web parts that the customer wishes to hide from the list.
So what we did eventually was to manage the list through code. Using a similar technique described in the article, Customizing MOSS 2007 My Sites within the enterprise, we ran a script to organize the web parts within each "My Site" web part gallery. The script essentially performs the following steps:
a. Get an instance of the web part gallery
b. Deletes all web parts in the gallery
c. Adds only the required web parts to the gallery.
And of course, it runs only once, when the site is created.
Getting an instance of the web part gallery
The first step in process is to get an instance of the web part gallery. Simply get an instance of the list named "Web Part Gallery" from the root web site.
Dim webPartGallery As SPList = SPContext.Current.Site.RootWeb.Lists("Web Part Gallery")
Deleting all web parts in the gallery
Next, we web ahead to delete all web parts in the list. Well, we could have skipped this step. But in our case, the requirement was to completely change the way the web parts were listed, so it didn't make much sense to keep the existing structure.
Dim webPartsCount As Integer = webPartGallery.ItemCount
Dim arrWebParts As New ArrayList()
For i As Integer = 0 To webPartsCount - 1
For Each webPartId As Integer In arrWebParts
Adding web parts to the gallery
Finally, we add web parts to the gallery. To do so, we create SPFile objects and upload them to the "/_catalogs/wp/" folder.
The idea is to build a string for the web part description file (*.dwp or *.webpart) and load it as a byte array to the folder. In this example, we create a method that builds up a *.dwp file.
Private Sub AddWebPartToGallery(ByVal assembly As String, ByVal typeName As String, ByVal title As String, ByVal description As String, ByVal partImageLarge As String, ByVal partImageSmall As String, ByVal web As SPWeb, ByVal webPartUrl As String, ByVal group As String, ByVal quickAddGroup As String)
Dim sb As New StringBuilder()
Dim sb As New StringBuilder()
sb.Append("<assembly>" + assembly + "</assembly>")
sb.Append("<typename>" + typeName + "</typename>")
sb.Append("<title>" + title + "</title>")
sb.Append("<description>" + description + "</description>")
sb.Append("<partimagelarge>" + partImageLarge + "</partimagelarge>")
sb.Append("<partimagesmall>" + partImageSmall + "</partimagesmall>")
Dim file As SPFile = web.Files.Add("_catalogs/wp/" + webPartUrl, New System.Text.UTF8Encoding().GetBytes(sb.ToString()), True)
file.Properties("Group") = group
file.Properties("QuickAddGroups") = quickAddGroup
What's nice about it is that you could also supply information about the Group and quick add groups as well. Which means you get to manage how the web parts are displayed in the web part gallery picker.
We could easily create a smiliar method that handles *.webpart files.
Here's an example that calls the AddwebPartToGallery() method to add a summary link web part to a custom group, "My Stuff".
AddWebPartToGallery("Microsoft.SharePoint.Publishing, Version=188.8.131.52, Culture=neutral, PublicKeyToken=71e9bce111e9429c", "Microsoft.SharePoint.Publishing.WebControls.SummaryLinkWebPart", "Summary Link Web Part", "Use to display links on your web page that can be grouped and styled and can be organized by dragging and dropping.", "/_layouts/images/webpart.gif", "/_layouts/images/webpart.gif", rootWeb, "SummaryLink.dwp", "My Stuff", "My Stuff")
And the end result of running the script is a web part gallery picker page that contains only the summary links web part in a category named, "My Stuff".