This article shows a way to remap a ghosted file to a new location, and also shows how to ghost a non-ghostable file, such as one originally created via SharePoint designer. This assumes a basic knowledge of SharePoint and the concept of ghosted and unghosted files.

This is actually a trick which overwrites the existing file with a new ghosted version. To actually modify a non-ghostable file so that it becomes ghostable is near on impossible without committing the cardinal sin of modifying the content database directly. An alternative is to delete the original and deploy the ghosted version in its place; however, problems arise with layouts (for example) that may still be referenced by existing content. I found the following technique overcomes these issues and allows files to be swapped out with a ghosted version seamlessly.

Note: if your desire is simply to reghost an existing file, then I recommend one of the many existing tools available, such as gl-reghostfile.

The Solution

In this example, we will remap the ArticleLeft layout from the SharePoint publishing template to an updated version deployed via our sample feature. This changes the location of the ghosted file to that of our feature, and allows us to deploy subsequent changes to the ArticleLeft layout by upgrading the new solution. The sample adds the word MODIFIED to the page title of the template.

The first step is to save out the existing file from the SharePoint database using the SharePoint designer. This is then added to a feature in the usual way as if you were provisioning it for the first time. In the case of layouts, be sure to also provision the properties from the original file; otherwise, the new layout will not behave correctly.

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="">
  <Module Url="_catalogs/masterpage" Path="Layouts">
    <File Url="ArticleLeft_Ghosted.aspx" 
         Type="GhostableInLibrary" IgnoreIfAlreadyExists="true">
      <Property Name="Title" 
         Value="Modified Article page with image on left" />
      <Property Name="MasterPageDescription" 
         Value="The modified article page with image on left contains 
                an image field and a rich text field." />
      <Property Name="ContentType" 
         Value="Page Layout" />
      <Property Name="PublishingPreviewImage" 
         Value="/_catalogs/masterpage/en-US/Preview Images/ArticleLeft.png, 
                /_catalogs/masterpage/en-US/Preview Images/ArticleLeft.png" />
      <Property Name="PublishingAssociatedContentType" 
         Value=";#Article Page;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007
                948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D;#" />

The next step is to rename the file so that it can initially be deployed alongside the the existing layout. In the example included, I have named the file ArticleLeft_Ghosted.aspx.

Lastly, we add a feature receiver with the following code to overwrite the target file with the new ghosted version. Note: this code has been simplified for brevity; see the sample for full code.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
    SPSite site = properties.Feature.Parent as SPSite;

    PublishingWeb pubweb = PublishingWeb.GetPublishingWeb(site.RootWeb);

    // get reference to newly provisioned file
    SPFile file = site.RootWeb.GetFile("/_catalogs/masterpage/ArticleLeft_Ghosted.aspx");
    if (file != null)
        // overwrite the old layout with the ghosted version
        file.MoveTo("/_catalogs/masterpage/ArticleLeft.aspx", true);

Once overwritten, the new version of the file remains ghosted. In the case of layouts and master pages, all existing content will begin to use the ghosted version. The key to the technique is the MoveTo command which allows any referenced layout to be overwritten without breaking references to existing content.