Situation: I'm deploying my SharePoint Publishing page layouts nicely through a feature – and I want to have WebParts for all users in the WebPartZones of my page layouts. Expected behaviour: When I create a new publishing page from my page layout, it will add the WebParts automatically (and pre-configured!) into the WebPartZones of my page. Should be an easy one, no? Have a look here, here, here and also here. I've spent several hours trying to figure out how I must prepare my WebPart definitions for the <AllUsersWebPart> section, how I could teach SharePoint not to create an additional WebPart on each Feature Activation, how… the list is long and painful. It works – sometimes, but sometimes is simply not enough for me.
So here comes my solution, maybe not as generic as the one from Microsoft, but in a certain way enhances even the functionality: I'm creating my own feature which I will call "PageLayoutsWebPartConfigurator" (actually, you could create multiple of those features, using the same FeatureReceiver-Implementation). What should this feature do? When I activate it, I would like to have the following behaviour:
- Read a configuration file that defines WebParts with full configuration information per PageLayout and within the Page Layout per WebPartZone.
- Add WebParts to the Page Layout if they are not present already.
- Update WebPart-Properties of already existing WebParts.
- Delete WebParts that are on the PageLayout but not anymore in my configuraion file.
- My Page Layouts remain uncostumized/ghosted so that changes on the Page Layout files (coming from another Feature) will be applied.
I will walk you piece by piece through the process of creating such a feature. I'm using Visual Studio 2008 with WSPBuilder. So create a WSP-Builder empty project and add the following elements:
The "feature.xml" file looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<Feature
Id="19FB512A-E40A-42f1-8978-E2A08DA35012"
Title="Page Layouts' WebPart Configuration"
Description="Adds, updates or deletes WebParts in page layouts based on a configuration file."
Version="1.0.0.0"
Hidden="FALSE"
Scope="Site"
DefaultResourceFile="core"
ReceiverAssembly="YourAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=yourpublickeytoken"
ReceiverClass="YourNameSpace.Receivers.PageLayoutsWebPartConfiguratorFeatureReceiver"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ActivationDependencies>
<!– Add dependencie(s) to page layouts feature(s) –>
</ActivationDependencies>
<ElementManifests>
<!– Configurations –>
<ElementFile Location="configuration.xml"/>
<!– WebParts –>
<ElementFile Location="WebPartsNewAndTopWebPart.webpart"/>
</ElementManifests>
</Feature>
Important here: Point to the feature receiver (don't forget to strong name your assembly and exchange my placeholders in the listing) and include our configuration file "configuration.xml" as well as all WebPart Definition files that you want to use (Use V3-Definitions, I haven't checked any other). Maybe it is also important to say that these WebPart Definition files will not be imported into the WebPart Gallery – instead they should be pre-configured WebParts that are added directly to the page layout. If you want them to appear as well in the WebPart-Gallery, add an additional "elements.xml" file and provision them.
Before I come to the "configuration.xml" file, let's have a look at the "WebParts" directory. As mentioned above, simply add the pre-configured WebParts you would like to add to your PageLayouts here. Example:
<webParts>
<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
<metaData>
<type name="YourNamespace.NewAndTopWebPart, YourAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=yourpublickeytoken" />
<importErrorMessage>Cannot import NewAndTopWebPart</importErrorMessage>
</metaData>
<data>
<properties>
<property name="HelpUrl" type="string" />
<property name="ExportMode" type="exportmode">All</property>
<property name="AllowMinimize" type="bool">True</property>
<property name="AllowEdit" type="bool">True</property>
<property name="Direction" type="direction">NotSet</property>
<property name="TitleIconImageUrl" type="string" />
<property name="AllowConnect" type="bool">True</property>
<property name="HelpMode" type="helpmode">Navigate</property>
<property name="AllowHide" type="bool">True</property>
<property name="Description" type="string">test</property>
<property name="Hidden" type="bool">False</property>
<property name="CatalogIconImageUrl" type="string" />
<property name="TitleUrl" type="string" />
<property name="AllowZoneChange" type="bool">True</property>
<property name="Height" type="unit" />
<property name="ChromeType" type="chrometype">Default</property>
<property name="Width" type="unit" />
<property name="Title" type="string">NewAndTopWebPart</property>
<property name="AllowClose" type="bool">True</property>
<property name="ChromeState" type="chromestate">Normal</property>
</properties>
</data>
</webPart>
</webParts>
Specify all WebPart-Properties to what you will need – you can still change them later but you must remember that this will only affect new pages created from the page layout (another thing i'm trying to overcome, stay tuned).
Now finally to the file "configuration.xml", our custom configuration:
<configuration>
<pageLayout filename="mypagelayout.aspx">
<webPart ID="415229C4-F1B8-4c44-96DB-2CDC728B2503" zoneID="Header" index="1" filename="NewAndTopWebPart.webpart" />
<webPart ID="415229C4-F1B8-4c44-96DB-2CDC728B2504" zoneID="CenterRightColumn" index="1" filename="NewAndTopWebPart.webpart" />
</pageLayout>
</configuration>
The following elements can be configured according to your needs:
| Element | Attribute | Description |
| pageLayout | filename | The filename of your page layout including the ".aspx" |
| webPart | ID | A (within the page layout) unique ID (GUID) for the WebPart. You can create any GUID for this – it will be used to find the WebPart within the FeatureReceiver |
| webPart | filename | The filename of the WebPart-Definiton file in your "WebParts" direcory. |
| webPart | zoneID | The ID of the WebPartZone where the WebPart should be placed. |
| webPart | index | The index within the WebPartZone where the WebPart should be placed. The first WebPart has the index 1. |
The filename of your page layout including the ".aspx"
A (within the page layout) unique ID (GUID) for the WebPart. You can create any GUID for this – it will be used to find the WebPart within the FeatureReceiver
webPart The filename of the WebPart-Definiton file in your "WebParts" direcory.
webPart webPart
Remarks:
- You can specify as many page layouts as you want.
- You can add as many WebParts to a PageLayout as you want.
- You can use the same WebPart-Definition file for multiple page layouts or even webparts in a pagelayout, however, make sure you use unique IDs.
Now with this knowledge and a prepared project proceed to Part 2 of my post!
