Copying publishing site pages

Publishing sites are just WSS sites with a special template. Though there is a separate namespace to help with the feature light-up specific to publishing sites. A very trivial scenario would be copying a page from a library, say the Pages library in a publishing site to say a Pages library in another Publishing site. For the sake of theory, let's consider that both the sites are part of the same site collection.

Looking at the SDK the obvious choice would have been churning out a piece of code that looked like:

 

SPSite site = new SPSite("https://MOSS");

PublishingSite psite = new PublishingSite(site);

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

PublishingPageCollection ppages = pweb.GetPublishingPages();

foreach (PublishingPage ppage in ppages)

{

if (ppage.Name == "Default.aspx")

{

ppage.ListItem.CopyTo("https://MOSS/PressReleases/Pages/" + ppage.Name);

pweb.Update();

}

}

 

This is what I would have agreed to as well. Until a very interesting behavior was brought to my attention. When the above code is executed, the file gets copied over as one would expect, however, what does not get copied over is the associated details such as the master page, the content types etc. In order to get a deep-copy so to speak one would need to get to the underlying SPFile objects and the code would in general look like:

 

SPSite site1 = new SPSite("https://blr3r01-13:20000");

SPSite site2 = new SPSite("https://blr3r01-13:20000/subsite1");

SPWeb web1 = site1.OpenWeb();

SPWeb web2 = site2.OpenWeb();

 

PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(site1.RootWeb);

PublishingPageCollection pubpageCollection = pubWeb.GetPublishingPages();

foreach(PublishingPage pubPage in pubPageCollection)

{

if(pubPage.Name == "SomePage.aspx"

{

SPFile file = web1.GetFile(pubPage.Url);

Byte[] binFile = file.OpenBinary();

string filename = file.Name;

 

SPFolder destFolder = web2.GetFolder("Pages");

if(destFolder != null)

{

file.CheckOut();

destFolder.Files.Add(filename, binFile, true);

file.CheckIn("temp");

file.Approve("temp");

}

foreach(SPFile destFile in destFolder.Files)

{

if(destFile.Name == filename)

{

destFile.Approve("temp");

}

}

}

}

 

With this you are all set to go.

 

-Harsh