Migrating Web Part Pages to Publishing Pages

Unfortunately, you cannot natively migrate web part pages to WCM publishing pages. The benefit of publishing pages manifests itself in the centralized page layouts. Web part pages cannot be modified universally, but publishing page layouts can be thusly modified.

So, to build a utility for migrating web part pages, it's a messy recipe. The result is only publishing pages with web parts intact, but not in the proper location nor is the page layout maintained; however, it is a better deal than to have to migrate web parts individually.

Start by making sure the web is a PublishingWeb:

if (PublishingSite.IsPublishingWeb)    return PublishingWeb.GetPublishingWeb(web);

Get all web part pages by looping through all document libraries and getting web part pages:

foreach (SPListItem item in doclib.Items) {    if (item.File.Url.EndsWith(".aspx")) {        WL("Adding web part page: {0}", item.File.Url);        webPartPages.Add(item.File.Url, item);        count++;    }}

Next, create a new publishing page from a selected page layout (BlankWebPartPage.aspx is a good one):

// get the blank web part page layoutList<PageLayout> layouts = new List<PageLayout>(pubWeb.GetAvailablePageLayouts());PageLayout layout = layouts.Find(    delegate(PageLayout l) {        return l.Name.Equals(pageLayoutName, StringComparison.CurrentCultureIgnoreCase);    });// get the pages collection and add the new publishing pagePublishingPageCollection pages = pubWeb.GetPublishingPages();// change the name of the new page if it already existsSPQuery query = new SPQuery();query.Query = "<Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='Text'>" + item.File.Name + "</Value></Eq></Where>";SPListItemCollection items = pubWeb.PagesList.GetItems(query);string pageName = item.File.Name;if (items.Count > 0) {    string fileExtension = DateTime.Now.ToString("_MMddyy_hhmmss");    pageName = pageName.Replace(".aspx", fileExtension+".aspx");}// create the new pagePublishingPage publishingPage = pages.Add(pageName, layout);publishingPage.Title = item.Title;

Get a few SPLimitedWebPartManagers to read the old web parts and store them and to create new web parts on the publishing page:

SPLimitedWebPartManager wppWpm = ((SPWeb)site).GetLimitedWebPartManager(item.File.Url, PersonalizationScope.Shared);SPLimitedWebPartManager publishingWpm = ((SPWeb)site).GetLimitedWebPartManager(item.File.Url, PersonalizationScope.Shared);

Now you've got to copy the web parts and save the publishing page:

foreach (WebPart oldWP in oldPageWpm.WebParts) {    // don't move the Title bar, it's already built into the page    if (oldWP.ToString().Equals("Microsoft.SharePoint.WebPartPages.TitleBarWebPart")) {        TitleBarWebPart titleBar = (TitleBarWebPart)oldWP;        // do steal the title bar property data, though        publishingPage.Title = titleBar.HeaderTitle;        publishingPage.Description = titleBar.HeaderDescription;    }StringBuilder sb = new StringBuilder();try {    // export the web part to a stream    oldWP.ExportMode = WebPartExportMode.All;    XmlWriter xwriter = XmlTextWriter.Create(sb);    wppWpm.ExportWebPart(oldWP, xwriter);    xwriter.Close();     // import the web part from the stream    string output = sb.ToString();    XmlReader xreader = XmlTextReader.Create(new StringReader(output));    string errorMessage;    WebPart newWP = publishingWpm.ImportWebPart(xreader, out errorMessage);    xreader.Close();    // check for import errors    if (!string.IsNullOrEmpty(errorMessage)) {        UpgradeLog(errorMessage, EventLogEntryType.Error);    }    // add the web part to the page    publishingWpm.AddWebPart(newWP, "Header", oldWP.ZoneIndex);}catch (Exception ex) {    Debug.WriteLine(ex.ToString());}}publishingPage.Update();