Programmatically adding Web Parts to Rich Content in SharePoint 2010


SharePoint 2010 ships with the great ability of adding Web Parts to content areas. This allows you to easily extend your content with dynamic elements providing your users with richer experience. Similarly to using Web Parts with Web Part Zones you should include Web Parts in Rich Content in your structured and repeatable deployment. There are however a few differences in how you provision Web Parts to Rich Content and knowing how it all works can make your life easier.

Programmatically adding Web Parts 101

Programmatically adding Web Parts in SharePoint 2010 is pretty simple. To add a Web Part from code you need two things a reference to the page to which you want to add the Web Part and a reference to the Web Part itself.

If you want to add a Web Part from a .webpart/.dwp file you have to import it first. You can do this using the SPLimitedWebPartManager.ImportWebPart method.

You can programmatically use a Web Part to a page using the following code snippet:

using (SPSite site = new SPSite("http://win2008/sites/publishing"))
{
    SPWeb web = site.RootWeb;
    SPFile page = web.GetFile("Pages/Lipsum.aspx");
    page.CheckOut();

    using (SPLimitedWebPartManager wpmgr = page.GetLimitedWebPartManager(PersonalizationScope.Shared))
    {
        XmlElement p = new XmlDocument().CreateElement("p");
        p.InnerText = "Hello World";
        ContentEditorWebPart cewp = new ContentEditorWebPart
        {
            Content = p
        };
        wpmgr.AddWebPart(cewp, "Header", 0);
    }

    page.CheckIn(String.Empty);
}

First we get a reference to the web where the page is located (1-3). Then we get a reference to the page itself (4). In order to add a Web Part to a page we need a reference to the SPLimitedWebPartManager (7). Then we instantiate a new Content Editor Web Part (11), we set some sample content (13) and we add it to the Header Web Part Zone on the page (15).

Publishing Page with Content Editor Web Part on it

Now we know how you can programmatically add Web Parts to pages, let’s take a look at the differences when adding Web Parts to Rich Content in SharePoint 2010.

Programmatically adding Web Parts to Rich Content

As mentioned before SharePoint 2010 allows you to edit Web Parts to Rich Content. Just like when adding Web Parts to Web Part Zones it’s possible to programmatically add Web Parts to Rich Content as well. Before we however start hacking the code let’s have a look how Web Parts in Rich Content actually work.

It’s a kind of magic…

If you know the ASP.NET Web Part architecture you know that in order for Web Parts to work like a Web Part, meaning supporting customization and personalization, it must live inside a Web Part Zone. If you add a Web Part outside a Web Part Zone it will be nothing more than a control with fixed settings. So how is it possible that Web Parts in SharePoint 2010 Rich Content work and behave like Web Parts while being added in content?

Web Parts in Rich Content are made possible in SharePoint 2010 using a trick. Under the hood SharePoint 2010 uses a hidden Web Part Zone which stores all Web Parts added to Rich Content. The exact location in the content, where the Web Part should be rendered is marked with a marker and during the page rendering process, the Web Part is being rendered and injected at the location specified by its marker. Thanks to this you can use all of the Web Part functionality together with the flexibility of enriching your content with dynamic functionality.

So how does the above changes the code that we need to programmatically add a Web Part to Rich Content?

Adding Web Parts to Rich Content using code

The code needed to programmatically add a Web Part to Rich Content is the same as when adding Web Parts to Web Part Zones for the most part. We still need a reference to the page and the Web Part. The differences are  around adding the Web Part to the page since we want the Web Part to be rendered in content instead of inside a Web Part Zone.

To better show you how adding Web Parts to Rich Content works I added some sample content to the page. I marked the location where the Web Part should be added with a | (pipe).

SharePoint 2010 Publishing Page with some sample content. Red arrow points to the | character which marks the place where the Web Part should be added.

You can a Web Part to Rich Content using the following code snippet:

using (SPSite site = new SPSite("http://win2008/sites/publishing"))
{
    SPWeb web = site.RootWeb;
    SPFile page = web.GetFile("Pages/Lipsum.aspx");
    page.CheckOut();

    using (SPLimitedWebPartManager wpmgr = page.GetLimitedWebPartManager(PersonalizationScope.Shared))
    {
        Guid storageKey = Guid.NewGuid();
        string wpId = String.Format("g_{0}", storageKey.ToString().Replace('-', '_'));

        XmlElement p = new XmlDocument().CreateElement("p");
        p.InnerText = "Hello World";
        ContentEditorWebPart cewp = new ContentEditorWebPart
        {
            Content = p,
            ID = wpId
        };
        wpmgr.AddWebPart(cewp, "wpz", 0);

        string marker = String.Format(CultureInfo.InvariantCulture, "<div class=\"ms-rtestate-read ms-rte-wpbox\" contentEditable=\"false\"><div class=\"ms-rtestate-read {0}\" id=\"div_{0}\"></div><div style='display:none' id=\"vid_{0}\"></div></div>", new object[] { storageKey.ToString("D") });
        SPListItem item = page.Item;
        string content = item["PublishingPageContent"] as string;
        item["PublishingPageContent"] = content.Replace("|", marker);
        item.Update();
    }

    page.CheckIn(String.Empty);
}

The first part is the same: as mentioned before we still need a reference to the web, the page and the SPLimitedWebPartManager. Nothing new here. Before we can add the Web Part to the page we have to set its ID (9-10, 17). This ID will be used by SharePoint during the rendering process to render the Web Part in the right place in Rich Content.

As mentioned before Web Parts placed in Rich Content are physically located in a hidden Web Part Zone. This Web Part Zone is called wpz. It’s a fixed prefix so it can be hardcoded in the code. In order to put the Web Part in Rich Content it has to be added to the wpz Web Part Zone (19).

The last part is to tell SharePoint to render the Web Part in a specific place in the Rich Content. To do this we have to replace the marker we placed in content with markup that will tell SharePoint what Web Part should be rendered there. This markup contains the ID of the Web Part which we specified before (21). Once we have the Web Part marker in place, we can edit the content and replace the marker with the Web Part marker (22-25).

After running the above code snippet we will get a Content Editor Web Part added to the given place in Rich Content:

SharePoint 2010 Publishing Page with some sample content. Red arrows points to a Content Editor Web Part added in Rich Content.

Summary

SharePoint 2010 allows to add Web Parts to Rich Content. This allows you to easily extend your content with dynamic functionality providing your users with richer functionality. Whether you’re using Web Parts in Web Part Zones or in Rich Content it’s important to have it both covered in your deployment story. Although in both cases you’re dealing with Web Parts, provisioning Web Parts in Rich Content is slightly different than adding them to Web Part Zones. Still it can be easily done in a supported fashion.

Technorati Tags: SharePoint 2010

Others found also helpful: