Showing posts with label ghosting. Show all posts
Showing posts with label ghosting. Show all posts

Thursday, 1 November 2007

Master pages/page layouts deployed as Feature not updating

Since Deploying master pages and page layouts as a Feature has been the most heavily commented article on this blog, and several of the posters seem to have run into the same problem, I wanted to write a quick post with some more information from my experiences on this.

So this is something of a non-standard post, feel free to tune out if it doesn't affect you ;-)

Anyway, I decided to do some more testing to see if either I'd got something wrong or if perhaps I was doing something differently to the people having problems. My test was basically to knock up a publishing site with a master page and page layout (associated with a custom content type as it often would be), then go through the update process. This is what I found:

  • making updates to the files (outside of the 12 folder) and then XCOPYing these to overwrite the files in the 12\TEMPLATE\features\MyFeature\ directory successfully updated the site. No need to deactivate/activate the Feature.
  • using a Solution package to deploy the files (when using Features this is generally what I do since I'm in a farm environment) - again this updated the site correctly when I upgrade the Solution (stsadm -o upgradesolution). This is to be expected since underneath the exact same thing is happening as in the previous test. (However, I also noticed occasionally the directory would complete disappear even after the solution upgrade had completed, or was there but still locked by another process, meaning the files could not be accessed even in Windows Explorer - this is slightly irritating but running the Solution upgrade again always succeeded.)
  • after causing the file to be customized (e.g. modifying or even just checking out with SPD), any subsequent updates to the files via the Feature/Solution did not appear on the site (though further updates in SPD are fine).

In short, this is all what I expected. Assuming the file has not been customized, anything which updates the copy on the filesystem will cause an update to the site. If it has been customized, updates on the filesystem will not (since the file has now been added to the content database, and the filesystem version is no longer used). If you've not come across this before, Considerations when using Features to deploy SharePoint files - ghosting/unghosting may help.

So, I'm guessing that if your master pages etc. are not updating when you overwrite the Feature files, it's because the files have become customized somehow. Unfortunately it's not so easy to tell for publishing files - for other files, SharePoint Designer provides a handy blue dot next to the file in it's Explorer view if the file is customized, but alas this doesn't happen for master pages/page layouts. The blue dot can be seen next to the AllItems.aspx file below (click to enlarge):



Unfortunately this also means reverting to the file on the filesystem is not straightforward either (we can't right-click the file in SPD and select 'Reset to site definition' as we can with other SharePoint files). So this can be a pain if you do want to keep your page layouts referenced from the filesystem (e.g. because performance is critical), but you've ended up in this state. It is possible to revert the files using the API though. I've not needed to do this myself, but the property to check is SPFile.CustomizedPageStatus and if this returns SPCustomizedPageStatus.Customized, then the SPFile.RevertContentStream() method can be used - this should cause SharePoint to henceforth use the version on the filesystem (though note you may lose some updates which had been made after the file was unghosted (customized) - you will need to re-apply these to the filesystem file after the reversion. And remember, don't use SPD for this or you'll be back where you started!)

So far, so (reasonably) straightforward.

However, one poster (deelpunt) had an interesting question about updating page layouts with web parts. As far as I can see, updating all page instances to have web parts in web part zones by updating the layouts will not be possible. This is because if web part zones are used, the web part is associated with the page instance rather than the page layout. Indeed, this can be the power of the architecture. It is possible to either:

  • have default web parts added to a zone when a page instance is created from a page layout. This can be done by deploying the page layout using a Feature, and using the AllUsersWebPart tag. This would not affect pages already created however.
  • add web parts to all the pages by adding them directly to the page markup in SPD, rather than in a zone. Of course, this then means the settings for the web part can only be modified by the page designer in SPD, rather than site users.
  • use the API to iterate through all pages in the site to add/modify webparts using SPFile.GetLimitedWebPartManager(). Needless to say, this is the kind of operation which requires a lot of care and planning in production!

As I've mentioned before, because of these issues the web part zone architecture is often not the best choice for scenarios such as WCM site development, since here we want our changes to apply across all pages which use the layout.

Hopefully this has been of some use. As always, leave a comment if you've had different experiences to those detailed here, I'd definitely be interested to hear.

[I also wanted to say sincere apologies to the commenters on the original post (and any others I've been slow in replying to) that it took a couple of weeks for me to come back. Something to do with my project going live and moving house at the same time, hopefully normal service now resumed ;-) ]

Wednesday, 4 July 2007

Considerations when using Features to deploy SharePoint files - ghosting/unghosting

In some of my earlier articles I talk about how to deploy various SharePoint artifacts as a Feature. In particular, 'Deploying master pages and page layouts as a Feature' discusses the idea of deploying these types of file (used in Publishing sites), but the concept applies to any file which will appear somewhere in a SharePoint list of some kind. In addition to the Master Page Gallery, other examples could include CSS/XSLT files being deployed to the Style Library, images to a picture library, and many other similar scenarios.

Occasionally people using this approach find that file updates can be difficult to apply. The process involves updating the Feature with the new version of the file, and then reinstalling and reactivating the Feature (typically the Feature version number will be incremented). In some cases the file updates successfully, in others it doesn't but there are no errors.

So what's going on?

The answer is that the file will not be updated (and therefore changes will not be seen in the browser for example) if that particular file has been 'unghosted' into the database.

<StartUnghostingExplanation>
[Without digressing too much, for anybody new to this concept it can be a confusing term which Microsoft are using less these days - the replacement term is 'customized' which is generally easier to understand. Depending on how they arrived in SharePoint, many files will initially only exist on the filesystem of the SharePoint front-end web servers. However, if such a file is customized e.g. it is checked out and edited (either through the UI, using SharePoint Designer etc.) SharePoint takes a copy of the file (now with modifications) and stores this in the content database instead of saving the changes back to the filesystem. This is the unghosting process. Whenever this file is requested in the future, the modified version from the database will be returned. This architecture allows SharePoint to scale to enterprise level, by only storing separate copies of files when absolutely necessary.]
<EndUnghostingExplanation>

When a file is provisioned in SharePoint using a Feature, SharePoint will copy the file to wherever your Feature specified, and will reference the file from this location. In many cases, this may actually be the 12\Template\Features directory. So in the case of master pages/page layouts etc. for example, when a web page is requested these resources will be retrieved from this location. Or at least, that's what happens if the file isn't customized.

If the file has been customized at some point, what happens when the Feature is updated is that the file on the filesystem is updated and reflects the changes, but SharePoint is now returning the copy in the database and so the update isn't reflected on the site!

So, if you want to use Features as your ongoing deployment strategy for your SharePoint document library (aka 'GhostableInLibrary') files, you should ensure the files can only be modified in this way. So files should not be modified either through the SharePoint UI or via SharePoint Designer. Typically, this won't be the case in the development environment but could be enforced for other environments. This means that unghosting is avoided, and SharePoint will continue to reference the copy on the filesystem.

Some other points of note:

  • Another advantage of this approach is that when a Solution is retracted, the files will also be removed.
  • Even a check-out/check-in operation without actual changes will cause SharePoint to see the file as customized, and will then be retrieved from the database rather than filesystem.
  • A file can be 'uncustomized' in SharePoint Designer by right-clicking on the file and selecting 'Revert to site definition'. However, this will obviously cause you to lose any changes you have made to the file from the original version!

So next time you are using a Feature and wondering why the file isn't being updated, consider if the file has been customized!