Share via


Office 365: Create Publishing Pages from XML

Applies To

  • Office 365
  • SharePoint 2007
  • SharePoint 2010

Scenario

We are researching a move from SharePoint 2007 to SharePoint Online. Regarding moving the actual content (publishing pages) options seems to be limited especially with regard to migrating towards using managed metadata columns. So what we wanted is the ability to read from an XML file and create publishing pages through sandboxed code. The sandboxed code can be deployed to SharePoint online and the xml can be created by custom farm-level code on the SharePoint 2007 farm.

Solution

The blog article Publishing in sandboxed solutions - Create a page contains the main code behind the sandboxed visual webpart that I created. The webpart depends on a pages.xml file that is the only file in the SiteCollectionDocuments folder (hey, this is only a Proof of Concept!). See below for the contents of the XML file and the code for the webpart.

I used the Visual webpart template in VS2012, set to sandbox solution for developing the webpart. This should work similarly in VS2010 with the Power tools extension installed.

Here's what to do once you have the solution available:

  1. Put pages.xml as the only file in the SiteCollectionDocuments folder of a publishing portal
  2. Deploy sandboxed solution to site
  3. Put CreatePages webpart on a webpart page
  4. Push the button and see if a page is created correctly in the Pages library of the root web

The XML

<?xml version="1.0" encoding="UTF-8" ?>
<Pages>
    <Page>
        <Name>PageFromXML.aspx</Name>
        <Title>Page created from XML file</Title>
        <PageLayout>/_catalogs/masterpage/ArticleLeft.aspx, ArticleLeft</PageLayout>
        <PageContent>Page created from XML file</PageContent>
    </Page>
</Pages>

The Code

using Microsoft.SharePoint;
using System;
using System.ComponentModel;
using System.IO;
using System.Text;
using System.Web.UI.WebControls.WebParts;
using System.Xml;
 
namespace CreatePages.VisualWebPart1
{
    [ToolboxItemAttribute(false)]
    public partial  class VisualWebPart1 : WebPart
    {
        // Uncomment the following SecurityPermission attribute only when doing Performance Profiling using
        // the Instrumentation method, and then remove the SecurityPermission attribute when the code is ready
        // for production. Because the SecurityPermission attribute bypasses the security check for callers of
        // your constructor, it's not recommended for production purposes.
        // [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Assert, UnmanagedCode = true)]
        public VisualWebPart1()
        {
        }
 
        protected override  void OnInit(EventArgs e)
        {
            base.OnInit(e);
            InitializeControl();
        }
 
        protected void  Page_Load(object  sender, EventArgs e)
        {
        }
 
        protected void  btnCreatePage_Click(object sender, EventArgs e)
        {
            SPFile aXmlFile= GetXmlFile();
 
            XmlDocument aXMLDoc = new  XmlDocument();
 
            byte[] bytes = aXmlFile.OpenBinary();
            Stream aMemStream = new  MemoryStream(bytes);
            aXMLDoc.Load(aMemStream);
 
            XmlNode aPageNameNode = aXMLDoc.SelectSingleNode("Pages/Page/Name");
            XmlNode aTitleNode = aXMLDoc.SelectSingleNode("Pages/Page/Title");           
            XmlNode aPageLayoutNode = aXMLDoc.SelectSingleNode("Pages/Page/PageLayout");
            XmlNode aPageContentNode = aXMLDoc.SelectSingleNode("Pages/Page/PageContent");
 
            string aPageName = aPageNameNode.InnerText;
            string aPageTitle = aTitleNode.InnerText;
            string aPageLayout = SPContext.Current.Site.Url + aPageLayoutNode.InnerText;           
            string aPageContent = aPageContentNode.InnerText;
 
            SPList aPagesList = SPContext.Current.Site.RootWeb.Lists["Pages"];
           
            PublishingPageCreator.AddPublishingPage(aPageName, aPageTitle, aPageLayout, aPagesList.RootFolder, aPageContent);
        }
 
        private SPFile GetXmlFile()
        {
            SPFolder aSiteColDocsFolder = SPContext.Current.Site.RootWeb.Folders["SiteCollectionDocuments"];
 
            SPFile afile = aSiteColDocsFolder.Files[0];
 
            return afile;
        }
 
        internal static  class CompiledTemplateStrings
        {
            internal static  string templateRedirectionPageMarkup = @"<%@ Page Inherits='Microsoft.SharePoint.Publishing.TemplateRedirectionPage, Microsoft.SharePoint.Publishing,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c' %><%@ Reference VirtualPath='~TemplatePageUrl' %> <%@ Reference VirtualPath='~masterurl/custom.master' %>";
        }
 
        internal class  PublishingPageCreator
        {
            private static  byte[] pageAsBytes;
            private static  readonly UTF8Encoding PageEncoder = new UTF8Encoding();
            internal static  byte[] GeneratePageStreamAsBytes()
            {
                if (pageAsBytes == null)
                {
                    byte[] bytes = PageEncoder.GetBytes(CompiledTemplateStrings.templateRedirectionPageMarkup);
                    pageAsBytes = new  byte[bytes.Length + 3];
                    pageAsBytes[0] = 0xef;
                    pageAsBytes[1] = 0xbb;
                    pageAsBytes[2] = 0xbf;
                    bytes.CopyTo(pageAsBytes, 3);
                }
                return pageAsBytes;
            }
 
 
            internal static  SPListItem AddPublishingPage(string name, string title, string layout, SPFolder folder, string aPageContent)
            {
                SPFileCollection files = folder.Files;
                byte[] file = GeneratePageStreamAsBytes();
                SPFile newFile = files.Add(name, file);
                SPListItem item = newFile.Item;
                item["ContentType"] = "HRSContentPage";
                item["ContentTypeId"] = "0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3905";
                item["PublishingPageLayout"] = layout;
                item["PublishingPageContent"] = aPageContent;
                item["Title"] = title;
                item.Update();
                newFile.CheckIn(string.Empty, SPCheckinType.MajorCheckIn);
                return item;
            }
        }
    }
}