Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

We have a couple of Enterprise Wiki's that were thought to be self-contained, but now want to consolidate the content together. I figured this would be easy, just open the Pages folder in Windows Explorer and copy the files to the new location.

Fortunately I wasn't that optimistic and attempted it with a single page first. The page does not display, giving an error of

This page is not using a valid page layout. To correct this problem, edit page settings and select a valid page layout.

Is there a specific migration method I should use or do I need to write a quick script or app to perform the migration?

If this must be scripted, what general direction should I be moving in?

Thanks

share|improve this question

2 Answers 2

If these are in the same site collection you might be able to move the individual pages using the Manage Content and Structure tool.

share|improve this answer
    
The existing wiki's are in several organically grown sites spread across different web applications. –  David Culp Apr 15 '11 at 12:54
    
If you have DocAve (avepoint.com ) available, One of the modules (Admin I think) can move items across site collections. Also, Gary Lapoint's free SharePoint Extensions ( blog.falchionconsulting.com/index.php/stsadmpowershell-commands ) also have the ability to move a list from site collection to site collection via command line import/export. If you can get all of your WIKIs into the same site collection that would at least be a good start –  Dave Wise Apr 15 '11 at 14:12
    
I set up a test setup with 3 wikis; first is RootWeb of the main site collection, second is a subsite of the same site collection and the third the RootWeb of a second site collection in the same web application. The Manage Content and Structure tool works fine from the second to the first, so I can verify that does indeed work. However, when I exported the third and imported it into the same web application as the destination wiki it no longer works. The wiki pages give the same error I mentioned in the initial question -- "This page is not using a valid page layout." –  David Culp Apr 15 '11 at 19:31
    
Looking at it again, I may not have been completely clear with the last point on the previous comment. What I mean is I exported the web (with sharepoint's backup capability) and then imported the web into the site collection with the destination wiki at it's root. I then tried to access the newly imported wiki and recieved the above error. Which means the backup/restore process failed. This is before I tried to move the pages to the new wiki, so the problem is in bringing the pages to a new site collection, not just moving them. I think that's clearer now. –  David Culp Apr 16 '11 at 4:38
    
Are these Wiki's small enough to be saved as a Site Template (with data)? IF so, then you could just add the STP over in the new site collection and create a site based off of it... –  Dave Wise Apr 16 '11 at 5:00
up vote 1 down vote accepted

After much research I found the solution and it turns out to be well known for importing pages to and from publishing sites. So why did it take me so long to find it. :(

The root cause is the lack of a means to correct the layout on a publishing page when moving it, with the result being the page's layout still points to the layout at the old location. That layout is no longer available because it's on a different web.

To fix the problem I wrote a quick one-off that loops thru the available layouts and re-assigns the layout with the same title to each page. The code is below.

One oddity is the the page layouts returned from GetAvailablePageLayouts() have web specific URLs, but they didn't work. Looking at the URLs of page in a site that worked revealed the layout URLs were site specific. Not sure why that is, but building the URL in the new layout value to be site specific worked.

Change the site and web urls to what you need them to be.

using System.Collections.Generic;
using System.Linq;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;

namespace FixPublishingPages
{
    class Program
    {
        static void Main()
        {
            using (var site = new SPSite("http://site"))
            using (var web = site.AllWebs["web"])
            {
                var pubWeb = PublishingWeb.GetPublishingWeb(web);

                var layoutValues = GetWebLayouts(pubWeb);

                var pages = pubWeb.PagesList;
                foreach (var page in pages.Items.Cast<SPListItem>())
                {
                    if (!PublishingPage.IsPublishingPage(page)) continue;

                    var layoutTitle = GetLayoutTitle(page);

                    CorrectPageLayout(page, layoutValues[layoutTitle]);
                }
            }
        }

        private static Dictionary<string, SPFieldUrlValue> GetWebLayouts(PublishingWeb pubWeb)
        {
            var layouts = new Dictionary<string, SPFieldUrlValue>();
            var webLayouts = pubWeb.GetAvailablePageLayouts();
            foreach (var availableLayout in webLayouts)
            {
                layouts[availableLayout.Title] = new SPFieldUrlValue
                                                     {
                                                         Description = availableLayout.Title,
                                                         Url = string.Format("{0}{1}", pubWeb.Web.Site.Url, availableLayout.ServerRelativeUrl)
                                                     };
            }
            return layouts;
        }

        private static string GetLayoutTitle(SPListItem page)
        {
            var pageLayout = (string)page[FieldId.PageLayout];
            return new SPFieldUrlValue(pageLayout).Description;
        }

        private static void CorrectPageLayout(SPListItem page, SPFieldUrlValue layoutValue)
        {
            var pubPage = PublishingPage.GetPublishingPage(page);

            if (pubPage.ListItem.File.CheckOutType != SPFile.SPCheckOutType.None)
                pubPage.ListItem.File.UndoCheckOut();

            pubPage.CheckOut();
            pubPage.ListItem[FieldId.PageLayout] = layoutValue;
            pubPage.ListItem.UpdateOverwriteVersion();
            pubPage.ListItem.File.CheckIn("Corrected page layout after import.", SPCheckinType.MajorCheckIn);
        }
    }
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.