Friday, May 1, 2009

Deploy Publishing Page and IgnoreIfAlreadyExists

For a project I was working on, I wanted to do a deployment of a SharePoint publishing page through a WSP and a Feature. I found a few blogs that assisted with me getting this started. Creating the actual Feature was not too hard but I run into a few issues.

The following is the Feature that I created.

<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
Id="64A687A4-B4DD-4742-8FE9-66191929D8BD"
Title="ML Demo KB Publishing Page Template"
Description="This feature will load the KB Publishing Page Template."
Version="1.0.0.0"
Scope="Site">
<ElementManifests>
<ElementManifest Location="Elements.xml"/>
<ElementFile Location="KBArticle.aspx"/>
</ElementManifests>
<ActivationDependencies>
<!--ML.Demo.KBMgt.WSS.CTypes-->
<ActivationDependency FeatureId="15A053C6-59DB-4a14-9CB6-3DB667634493" />
</ActivationDependencies>
</Feature>


<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="KBPageLayoutsModule" Url="_catalogs/masterpage" RootWebOnly="True" Path="">
<File Url="KBArticle.aspx" Name="KBArticle.aspx" IgnoreIfAlreadyExists="TRUE" Type="GhostableInLibrary">
<Property Name="Title" Value="KB Article"></Property>
<Property Name="ContentType" Value="KB Article"></Property>
<Property Name="PublishingAssociatedContentType" Value=";#KB Article;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F200
7948130EC3DB064584E219954237AF3900
242457EFB8B24247815D688C526CD44D00
DECC999E401842A08C5F380CB73E0191;#"
></Property>
</File>
</Module>
</Elements>

In this feature I am doing several things:

  • I am deploying to the Master Page Gallery because the Feature has Site scope, the Module Url is set to _catalogs/masterpage, File Type is set to GhostableInLibrary.
  • I have a Feature dependency on another Feature that is responsible for deploying a custom content type. I could have combined these all into one Feature however I like keeping them separate.
  • When creating the publishing page I simply created it through SharePoint Designer, I then viewed the code and copy and pasted it into an aspx within my solution in Visual Studio. I really do not want to rely on SharePoint Designer over the long term.
  • In the File element I specify Properties which are used to set values into the columns within the Master Page Gallery library. For instance I set the title and content type association for the publishing page.

Remember that if you cannot use Features to do a production deployment, you should really rethink your deployment and configuration management procedures for your SharePoint environment over the long run. Otherwise your environment will become a mess of one-off solutions with no way to redeploy solutions across development, quality assurance, staging and production. In this case I know I could have simply gone into the SharePoint user interface, manually create the content type and then associate a publishing page to the content type via SharePoint Designer – however that is not really that repeatable from a deployment perspective.

The first challenge I ran into was trying to understand how the IgnoreIfAlreadyExists attributed actually worked. According to the documentation on MSDN, if IgnoreIfAlreadyExists is set to TRUE, it will suppress any errors if the file has already been loaded into the Master Page Gallery and continue uploading. I found several blogs providing incorrect information claiming that the IgnoreIfAlreadyExists does not work as intended. My experience was it works. When I did the deployment the new Publishing page does get pushed up. I say this because I would look at pages that were referencing the publishing page and the changes would be reflected. HOWEVER the deceiving thing is if you look at the entry in the Master Page Gallery, neither the time date stamp nor version will be updated making you think that the change was not applied.

Another interesting thing was if you deactivate this Feature the publishing aspx page will remain in the Master Page Gallery even if the publishing page is not being referenced anywhere. I had initially assumed SharePoint was keeping the publishing page there because it is not possible to delete a publishing page it is referenced. The only way you remove the publishing page is to create a Feature event handler for ondeactivation to delete it manually from the Master Page Gallery. Remember if you do this you can get an exception saying "This item cannot be deleted because it is still referenced by other pages" if the publishing page is being used anywhere.

Another issue I ran into was trying to update the properties of the publishing page in the Master Page Gallery. No matter what I do, if I change the file properties in the Feature, the changes would not take be visible in the Master Page Gallery. This is some related to the first issue I had. Anyways, I determined the only way to update the entry the Master Page Gallery is to put an onactivation event handlers onto the Feature.

References:

No comments: