Microsoft Content Management Server 2002 Technical Articles
Mapping MCMS 2002 APIs to SharePoint Server 2007
 

Microsoft Corporation

May 2006

Applies to:
    Microsoft Content Management Server 2002
    Microsoft Office SharePoint Server 2007

Summary: The services previously provided by Microsoft Content Management Server (MCMS) 2002 are now provided by Microsoft Office SharePoint Server 2007. SharePoint Server is built upon Microsoft Windows SharePoint Services (version 3). This article helps you determine how the MCMS Publishing API (PAPI) maps to an equivalent but different Publishing API in SharePoint Server 2007. (33 printed pages)

Contents

Introduction
MCMS Namespaces
Architectural Changes
Common PAPI Tasks
MCMS Customization
Site Deployment API Tasks
Conclusion
Additional Resources

Introduction

Many of the tasks involved in the development of a Web site are related to customizing it for particular business needs. Some of these customizations are related to the site appearance and some to the functionality provided by the Web site. In Microsoft Content Management Server (MCMS) 2002, the developer had to perform most of these tasks by using the MCMS Publishing API (PAPI), which provides access to the underlying MCMS object model.

By default, Microsoft Office SharePoint Server 2007 provides significant Web content publishing features; most tasks that required custom code in MCMS can be accomplished by configuration of existing capabilities and do not require custom code. A powerful Publishing API is always available for tasks that require special customizations. This article helps you determine how the MCMS PAPI maps to an equivalent but different Publishing API in SharePoint Server 2007.

Office SharePoint Server 2007 is built on Microsoft Windows SharePoint Services (version 3). As a result, many Windows SharePoint Services features are exposed by default, and the infrastructure allows customization to be performed without any coding. However, there are business scenarios where you may need extended customization.

Due to the technology shift, a new API has been created for SharePoint Server 2007 to work together with Windows SharePoint Services V3. The managed and COM-based APIs in MCMS 2002, including the site deployment API, have been entirely replaced by managed code.

This article is organized by MCMS 2002 concepts. Each section compares the MCMS topic to the equivalent topic in SharePoint Server 2007 or Windows SharePoint Services.

This article does not address configuration or step-by-step instructions for SharePoint Server, but instead points to the object model classes so you can learn where to look for more information.

MCMS Namespaces

All managed libraries provided with MCMS 2002 begin with the Microsoft.ContentManagement prefix. The equivalent functionality in Office SharePoint Server 2007 is provided by classes mostly in the Microsoft.SharePoint and Microsoft.SharePoint.Publishing namespaces. Table 1 describes how the MCMS namespaces map to the SharePoint Server and Windows SharePoint Services namespaces.

Table 1. Namespace mapping from MCMS 2002 to SharePoint Server 2007 and Windows SharePoint Services V3

MCMS Namespace SharePoint Server or Windows SharePoint Services Namespace
Microsoft.ContentManagement.Publishing

Provides the core classes. Works with channels, postings, template galleries, templates, resource galleries, and resources.

Microsoft.SharePoint.Publishing

Provides the core classes. It works with PublishingWebs, PublishingPages, PageLayouts, Master Page and Page Layout Gallery, Image Library, and Document Library.

For details, see the Microsoft.SharePoint namespace (http://msdn2.microsoft.com/en-us/microsoft.sharepoint(office.12).aspx) and Microsoft.SharePoint.Publishing Namespace (http://msdn2.microsoft.com/en-us/microsoft.sharepoint.publishing(office.12).aspx).

Microsoft.ContentManagement.Events

Provides classes that work with the MCMS event model.

This event model is no longer supported, but there are equivalent events in Windows SharePoint Services.

The Microsoft.SharePoint namespace (http://msdn2.microsoft.com/en-us/microsoft.sharepoint(office.12).aspx) provides classes with methods for handling events that occur for items or lists.

For details, see Event Fundamentals (http://msdn2.microsoft.com/en-us/ms442323(office.12).aspx).

SharePoint Server is integrated with Microsoft Windows Workflow Foundation (WF), which provides an entire workflow engine that can handle many of the custom workflows performed in MCMS.

Microsoft.ContentManagement.Extensions.Placeholders

Provides classes that get/set content from the built-in placeholders for use on templates and building custom placeholders.

These classes map to classes in the Microsoft.SharePoint.Publishing.Fields namespace (http://msdn2.microsoft.com/en-us/microsoft.sharepoint.publishing.fields(office.12).aspx).
Microsoft.ContentManagement.Extensions.Placeholders.Office

Provides classes that work with Authoring Connector.

SharePoint Server replaces the Authoring Connector with a feature that allows converting a Microsoft Office system document to HTML and saving it in a specific HTML field on the designed page layout. For more information, see Page Publishing Using Document Converters (http://msdn2.microsoft.com/en-us/ms549211(office.12).aspx).
Microsoft.ContentManagement.Web

Provides classes that work with Microsoft ASP.NET Web applications.

The primary use of these classes was for support of VaryByCustom Output caching. In SharePoint Server, this is done through a site setting and custom cache profiles.
Microsoft.ContentManagement.Web.Caching

Provides classes that govern caching behavior of postings.

There is no direct equivalent in SharePoint Server because most of these tasks are not handled by SharePoint Server. They are configured now by using the Central Administration user interface. Also different cache profiles can be created for page layouts.
Microsoft.ContentManagement.Web.Security

Provides classes that are used for custom authentication methods.

SharePoint Server relies on the ASP.NET 2.0 membership provider model. The classes in System.Web.Security such as System.Web.Security.MembershipProvider will be used instead.

SharePoint Server and Windows SharePoint Services provide an even more robust API that includes several other namespaces and Web services.

Architectural Changes

Office SharePoint Server 2007 has a different architecture from MCMS 2002 because it is based on Windows SharePoint Services. Windows SharePoint Services Web sites are composed of a collection of sites, and sites can contain other sites or lists. Notice that the SharePoint API encapsulates sites as SPWeb objects. Lists have columns and the content of these columns is filled through ASPX forms that use field controls. Additionally, the SharePoint foundation provides security, versioning, and workflow at the item level in the list. The list concept has proved to be simple and powerful enough to address many business needs.

SharePoint Server 2007 provides a Publishing feature. As with MCMS 2002, the Publishing feature is a template-based page rendering system.

The two fundamental templates used for page rendering are master pages and page layouts. Page layouts can be used by all page instances that are based on that page layout. They are .aspx files very similar to MCMS templates files. Master pages can be used by all page instances in a site. Page layouts are stored as list items in the Master Page and Page Layout Gallery, so you can use versioning, check-in and check-out, workflow, and other features available for SharePoint document libraries.

A SharePoint PublishingWeb object (the equivalent of a channel in MCMS) is a SharePoint site that has a special SharePoint list, by default called Pages, which will contain items also referred to as pages (these pages are similar to MCMS postings). These pages are created with page layouts that use field controls (the equivalent of placeholder controls in MCMS).

To get a better understating of the page processing in SharePoint Server, see Page Processing Model (http://msdn2.microsoft.com/en-us/ms498550(office.12).aspx).

Table 2 provides a quick reference to the commonly used Windows SharePoint Services and SharePoint Server classes.

Table 2. Commonly used Windows SharePoint Services and SharePoint Server classes

Class Name Description
Microsoft.SharePoint.SPWeb (http://msdn2.microsoft.com/en-us/microsoft.sharepoint.spweb(office.12).aspx) The SPWeb class represents a SharePoint Web site, often referred to as a site.
Microsoft.SharePoint.SPList (http://msdn2.microsoft.com/en-us/microsoft.sharepoint.splist(office.12).aspx) The SPList class represents a list on a SharePoint Web site.
Microsoft.SharePoint.SPListItem (http://msdn2.microsoft.com/en-us/ms415089(office.12).aspx) The SPListItem class represents an item, or row, in a list.
Microsoft.SharePoint.Publishing.PublishingWeb (http://msdn2.microsoft.com/en-us/microsoft.sharepoint.publishing.publishingweb(office.12).aspx) The PublishingWeb class provides access for publishing features on an SPWeb object, like the pages collections, executing queries to get particular pages, or access to other PublishingWeb objects in the site hierarchy.
Microsoft.SharePoint.Publishing.PublishingPage (http://msdn2.microsoft.com/en-us/microsoft.sharepoint.publishing.publishingpage(office.12).aspx) The PublishingPage class provides access for publishing features on an SPListItem object.
Note   A page in SharePoint Server is an SPListItem stored on a special kind of SPList object.
Microsoft.SharePoint.SPSite (http://msdn2.microsoft.com/en-us/ms462369(office.12).aspx) The SPSite class represents a collection of sites on a virtual server, including a top-level site and all its subsites.

CmsHttpContext

MCMS 2002 creates a Microsoft.ContentManagement.Publishing.CmsHttpContext object for every request to a posting or channel. This object is the entry point to other objects like channels or postings. Most of the MCMS 2002 custom code uses a reference to this object.

Office SharePoint Server 2007 has a similar concept implemented by the class Microsoft.SharePoint.SPContext (http://msdn2.microsoft.com/en-us/microsoft.sharepoint.spcontext(office.12).aspx). This object also works as an entry point for pages or sites.

Table 3 shows the mapping of common CmsHttpContext properties to SPContext properties. The code sample assumes that the Microsoft.SharePoint and Microsoft.SharePoint.Publishing namespaces have been imported.

Table 3. CmsHttpContext properties to SPContext properties

CmsHttpContext Properties SPContext Properties
Channel PublishingWeb.GetPublishingWeb(SPContext.Current.Web);
Posting SPContext context = SPContext.Current; PublishingPage currentPage = PublishingPage.GetPublishingPage(context.ListItem);
RootChannel PublishingWeb.GetPublishingWeb(SPContext.Current.Web.Site.RootWeb);
User SPContext.Current.Web.CurrentUser

Channel

In MCMS 2002, channels are used to store, organize, and manage access to postings. Channels are arranged in a hierarchy that has a single channel at its root.

In the Office SharePoint Server 2007 object model, channel objects are mapped to Microsoft.SharePoint.SPWeb objects. An SPWeb instance represents a SharePoint site. To access publishing features, you use Microsoft.SharePoint.Publishing.PublishingWeb in conjunction with your SPWeb instance to access all of the publishing features.

The following code example shows how the SharePoint Server 2007 object model is used to enumerate a list of sites within the current site collection.

namespace Samples
{
    using System;
    using System.ComponentModel;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Publishing;
    public class EnumerateSitesInSiteCollection : WebControl
    {
        protected void ListWebs(PublishingWeb publishingWeb, 
           HtmlTextWriter output)
        {
            output.Write(string.Format("<A href=\"{0}\">{1}</A>", 
               publishingWeb.Url, publishingWeb.Title));
            foreach (PublishingWeb childPublishingWeb in 
               publishingWeb.GetPublishingWebs())
            {
                ListWebs(childPublishingWeb, output);
            }
        }

        protected override void RenderContents(HtmlTextWriter output)
        {
            SPSite site = SPContext.Current.Site;
            output.Write("<H1>Sites in Site Collection</H1><BR>");
            foreach (SPWeb web in site.AllWebs)
            {
                if (PublishingWeb.IsPublishingWeb(web))
                {
                    PublishingWeb publishingWeb = 
                       PublishingWeb.GetPublishingWeb(web);
                    ListWebs(publishingWeb, output);
                }
            }
        }
    }
}

Table 4 shows the mapping of common Channel properties to SPWeb properties.

Table 4. Mapping common Channel properties to SPWeb properties

MCMS Channel Property SharePoint Server 2007 PublishingWeb property
AllChildren No direct equivalent. Use the GetPublishingPages() and GetPublishingWebs() mappings together.
Channels GetPublishingWebs()
CreatedBy CreatedBy
CreatedDate CreatedDate
CustomProperties Web.AllProperties
DefaultPostingName DefaultPage.Name
DefaultTemplateGallery GetAvailablePageLayouts()
Description Description
DisplayName Title
DisplayPath No direct equivalent
ExpiryDate No direct equivalent

Sites in Windows SharePoint Services do not have a publishing schedule like MCMS Channels. Sites will be hidden from navigation based on the scheduling data of the welcome page: DefaultPage.EndDate

LastModifiedBy No direct equivalent
LastModifiedDate LastModifiedDate
Name Name
Parent ParentPublishingWeb
OuterScriptFile MasterUrl
Postings GetPublishingPages()
IsRoot IsRootWeb
Url
UrlUnpublished
UrlPublished
Url.

The SPWeb equivalent for UrlUnpublished and UrlPublished is still Url because SharePoint Server 2007 does not change the URL based on the publishing mode.

Posting

In MCMS 2002 a Posting object represents a posting stored in a channel. An MCMS 2002 posting is a collection of references to the parts (the page template, resources, and placeholders) that compose the HTML page. A posting also has a schedule: The posting is visible to the subscribers browsing your MCMS 2002 site only between the posting start date and expiration date. Postings use the security settings of their channel, and when editing with a Web browser, it uses those of the folder storing the page they are based on.

The page template that the posting references is responsible for the layout and the number and location of placeholders.

In Office SharePoint Server 2007, postings are mapped as Microsoft.SharePoint.Publishing.PublishingPage (http://msdn2.microsoft.com/en-us/microsoft.sharepoint.publishing.publishingpage(office.12).aspx) objects. Pages are stored as Microsoft.SharePoint.SPListItem (http://msdn2.microsoft.com/en-us/ms415089(office.12).aspx ) objects. A page stores its content in the columns of the SPListItem object. Pages use the security settings of their SPList objects, and security settings can also be set at the page level.

The page layout that Microsoft.SharePoint.Publishing.PublishingPage references is responsible for the layout and the number and location of field controls.

Table 5 shows the mapping of common Posting properties to Page properties.

Table 5. Mapping common Posting properties to Page properties

MCMS Posting Property SharePoint Server PublishingPage Property
CreatedBy CreatedBy
CreatedDate CreatedDate
CustomProperties ListItem["custompropertyname"]

MCMS custom properties are mapped as columns on the target SharePoint Server page.

Description Description
DisplayName Title
DisplayPath No direct equivalent
ExpiryDate EndDate
IsHiddenModePublished IncludeInNavigation
LastModifiedBy LastModifiedBy
LastModifiedDate LastModifiedDate
Name Name
Path Url
Parent PublishingWeb
Placeholders[FieldName] ListItem[FieldName]
StartDate StartDate
Template Layout
Url Url

Placeholder Control

In MCMS 2002, a placeholder control is an ASP.NET-based server control that provides the user interface for a placeholder in both the authoring and presentation modes. A placeholder control also has an associated placeholder definition.

However, three types of classes in the Publishing API exist in both MCMS and SharePoint Server: Schema objects, Data objects, and Control objects, which are used in the graphical user interface.

Schema Classes

These classes define the name and any schema-level settings for a "column" of data in the schema for a type of page. In MCMS 2002, schema classes are placeholder definition classes configured and stored on Template Gallery items; in SharePoint Server, they are field types configured and stored in content types. Table 6 shows a mapping of common MCMS 2002 schema classes to SharePoint Server 2007 classes.

Table 6. Common MCMS 2002 schema classes compared to SharePoint Server 2007 classes

MCMS 2002 Class SharePoint Server 2007 Class
PlaceholderDefinition SPField (Windows SharePoint Services base class)
HtmlPlaceholderDefinition HtmlField
ImagePlaceholderDefinition ImageField
AttachmentPlaceholderDefinition LinkField

SharePoint Server publishing field types are in the Microsoft.SharePoint.Publishing.Fields namespace.

Note   Most of the constraints properties that in MCMS are configured on the placeholder definition classes are now specified in SharePoint Server as properties of the field controls in the layout ASPX markup.

Data Classes

These are the class objects used to return the actual instance of the data for an individual page in a given "column". In MCMS 2002, data classes are placeholder objects retrieved from Posting objects; in SharePoint Server, they are different kinds of simple data types retrieved from the SPListItem object. Table 7 shows a mapping of common MCMS 2002 data classes to SharePoint Server 2007 classes.

Table 7. Common MCMS 2002 data classes compared to SharePoint Server 2007 classes

MCMS 2002 Class SharePoint Server 2007 Class
Placeholder Windows SharePoint Services stores any general object types in their list item fields (for example, DateTime, String, and so on)
HtmlPlaceholder String (now a simple string, not a special object)
ImagePlaceholder ImageFieldValue
AttachmentPlaceholder LinkFieldValue

SharePoint Server Image and Link value classes are in the Microsoft.SharePoint.Publishing.Fields namespace.

Note   In MCMS 2002 you can always retrieve a Placeholder object from a Posting for a given field name and then set its properties directly, and they are reflected in the posting. In SharePoint Server, when you retrieve a value from an SPListItem object, it may be null if there is no current value. Also, setting properties on an ImageFieldValue or LinkFieldValue is not reflected in the SPListItem object until you set the LinkFieldValue or ImageFieldValue back into the SPListItem object. The following code example shows how to get or set these values.
PublishingPage p;
// Code to retrieve page object p
LinkFieldValue linkValue = p.ListItem["link1"] as LinkFieldValue;
if (null == linkValue)
{
// This field is currently empty as it has no value, so construct 
// a new one
linkValue = new LinkFieldValue();
}
linkValue.NavigateUrl = text1;  
// text1 is a URL string
// You must set the updated value object back into the list item
p.ListItem ["link1"] = linkValue;
String htmlValue = p.ListItem ["html1"] as String;
// You can append new HTML to the old HTML value or just set the value 
// to a new string of HTML
p.ListItem ["html1"] = htmlValue + text2;  // text2 is a string of HTML
ImageFieldValue imageValue = p.ListItem ["image1"] as ImageFieldValue;
if(null == imageValue)
{
// This field is currently empty as it has no value, so construct a new 
// one
    imageValue = new ImageFieldValue();
}

imageValue.ImageUrl = text3;  // text3 is a URL string
// You must set the updated value object back into the list item
p.ListItem ["image1"] = imageValue;
p.ListItem.Update();

Control Classes

These are ASP.NET controls in the markup for the layout ASPX that bind to a "column" of data for a page by name and enable it to be displayed and edited on a Web page in the Web author. In MCMS 2002, control classes are placeholder control classes bound to a placeholder definition by their PlaceholderToBind property; in SharePoint Server, they are field controls bound to an SPField by their FieldName property. Table 8 shows a mapping of common MCMS 2002 control classes to SharePoint Server 2007 classes.

Table 8. Common MCMS 2002 control classes compared to SharePoint Server 2007 classes

MCMS 2002 Class SharePoint Server 2007 Class
BasePlaceholderControl BaseFieldControl
HtmlPlaceholderControl RichHtmlField
SingleImagePlaceholderControl RichImageField
SingleAttachmentPlaceholderControl RichLinkField

SharePoint Server publishing field control classes are in the Microsoft.SharePoint.Publishing.WebControls namespace.

Note   Most of the constraints properties that in MCMS used to be configured on the placeholder definition classes are now specified in SharePoint Server as properties of the field controls in the layout ASPX markup.

There is a distinction between the control level data for the values, which reflects the current values in the Web author that may not yet be saved, and the page level data as it is currently saved in the store.

In MCMS, the control level data is retrieved through individual properties on the placeholder controls, similar to those on the placeholder data object (for example, Html and NavigateUrl). The page level data is retrieved by the BoundPlaceholder property, which gets the placeholder object value as it is currently stored in the Posting object.

In SharePoint Server, the control level data is retrieved through the field control Value property, which returns a value object of the correct type reflecting the current Web author values. The page level data is retrieved through the ItemFieldValue property on the control, which returns the value as it is currently stored in the SPListItem object.

Searches

You can use the Searches class provided by the MCMS PAPI to get direct access to any object in MCMS. Following are the four most-used methods to access this object in MCMS:

  • Searches.GetByPath   Uses the path of the object to find it. The path concept is not present in SharePoint Server 2007.

    An equivalent SharePoint Server 2007 API code example to perform a Searches.GetByPath is shown.

    SPWeb rootWeb = SPControl.GetContextWeb(this.Context).Site.RootWeb;
    PublishingWeb pweb = PublishingWeb.GetPublishingWeb(rootWeb);
    string path = "/Channel1/ChannelSub1";
    foreach (string pathPart in 
      path.Split(new char[]{'/'},
                  StringSplitOptions.RemoveEmptyEntries))
    {
         pweb = pweb.GetPublishingWebs()[pathPart];
    }
    

    However, this code will not be performant.

  • Searches.GetByGUID   Uses the GUID of the object to find it.

    GUIDS will have different values from MCMS to SharePoint Server, but most objects in SharePoint Server will have a GUID. For a PublishingPage object, use ListItem.UniqueID; for PublishingWeb use Web.ID.

    There are no built-in methods for searching elements by GUID, but because everything in SharePoint Server is a list, you can use GUIDs to get to particular elements. The following code example shows this.

    //Getting a PublishingPage by GUID
    PublishingWeb publishingWeb = null;
    //Code to access PublishingWeb
    SPListItem item = publishingWeb.PagesList.Items[new Guid("{FFFFFFFF-
        FFFF-FFFF-FFFF-FFFFFFFFFFFF")];
    PublishingPage page = PublishingPage.GetPublishingPage(item);
  • Searches.GetPostingsByCustomProperty   When you migrate a site from MCMS to SharePoint Server, custom properties on postings are migrated as columns. To get a list of items with a specific value on a column you can use the following code.
    SPWeb rootWeb = 
       SPControl.GetContextWeb(HttpContext.Current).Site.RootWeb;
    SPList list = rootWeb.Lists[new Guid("{FFFFFFFF-FFFF-FFFF-FFFF-
       FFFFFFFFFFFF")];
    SPQuery query = new SPQuery();
    query.Query =
    "<Where><Eq><FieldRef Name=\"MyColumn\" />" +
    "<Value Type=\"Text\">ValueA</Value></Eq></Where>";
    SPListItemCollection items = list.GetItems(query);
    
  • Searches.GetByURL   Uses the URL of the object to find it. The equivalent SharePoint Server 2007 API to perform a Searches.GetByURL will be as follows.
    //To get a PublishingWeb (the SharePoint Server 2007 equivalent 
    // of a CMS channel)
    PublishingWeb pweb = PublishingWeb.GetPublishingWeb(new 
       Uri("http://localhost:2851/woodgroove"));
    

Common PAPI Tasks

The following sections provide code examples that indicate how common MCMS PAPI tasks are performed in SharePoint Server 2007.

Getting the CmsContext

In MCMS 2002:

CmsHttpContext cmsContext = CmsHttpContext.Current;

In SharePoint Server 2007:

SPContext spContext = SPContext.Current;

Getting the Root Channel

In MCMS 2002:

Channel rootChannel = cmsContext.RootChannel;

In SharePoint Server 2007:

SPWeb rootWeb = spContext.Web.Site.RootWeb;

Creating Channels

In MCMS 2002:

Channel channel = cmsContext.Channel;
Channel newChannel =  channel.CreateChannel();
newChannel.Name = "name";
newChannel.DisplayName = "displayname";
newChannel.Description = "Description";
cmsContext.commitAll();

In SharePoint Server 2007:

SPWeb web = SPControl.GetContextWeb(Context);
   PublishingWeb pubWeb = PublishingWeb.GetPublishingWeb(web);
   PublishingWeb newWeb = pubWeb.GetPublishingWebs().Add("name");
   newWeb.Title = "displayName";
   newWeb.Description = "description";
   newWeb.Update();

Creating Postings

In MCMS 2002:

Channel channel = cmsContext.Channel;
Template mytemplate = cmsContext.Searches.GetByPath("path to template") 
   as Template;
Posting newPosting;
newPosting = channel.CreatePosting(mytemplate);
newPosting.Name = "name";
newPosting.Description = "Description";
HtmlPlaceholder pagecontent;
pagecontent = newPosting.Placeholders["Page Content"] as HtmlPlaceholder;
pagecontent.Html = " Hello World!";
cmsContext.CommitAll();

In SharePoint Server 2007:

SPWeb web = SPControl.GetContextWeb(HttpContext.Current);
PublishingWeb publishingweb = PublishingWeb.GetPublishingWeb(web);
PageLayout layout = null;
SPContentTypeId contentType = new SPContentTypeId();
// Code to set the content type ID
PageLayout[] layouts = publishingweb.GetAvailablePageLayouts(contentType);
if (layouts != null && layouts.Length > 0)
{
layout = layouts[0];
PublishingPage newPage;
newPage = publishingweb.GetPublishingPages().Add("name", layout);
newPage.Description = "Description";
newPage.ListItem["Page Content"] = " Hello World";
newPage.Update();
}

Enumerating Postings

In MCMS 2002:

Channel channel = cmsContext.Channel;
htmlTextWriter.Write("<H1>Posting in current Channel</H1><BR>");
foreach (Posting p in channel.Postings)
{
   htmlTextWriter.Write("<A href=\""+ p.Url + ">"+ p.DisplayName+ "</A>");
}

In SharePoint Server 2007:

PublishingWeb publishingweb = 
   PublishingWeb.GetPublishingWeb(SPContext.Current.Web);
htmlTextWriter.Write("<H1>Pages in current Site</H1><BR>");
PublishingPageCollection pages = publishingweb.GetPublishingPages();
foreach (PublishingPage page in pages)
{
   htmlTextWriter.Write("<A href=\"" + page.Url + ">" + page.Name + 
      "</A>");
}

Accessing Postings

A common task in MCMS 2002 is to create code to get to a particular posting and then set or get the information contained in that posting.

Getting Posting Values

In MCMS 2002:

Posting p = null;
//Code to get to the posting
AttachmentPlaceholder att = p.Placeholders["attachment1"] as 
   AttachmentPlaceholder;
String attachmentText = att.AttachmentText;
HtmlPlaceholder html = p.Placeholders["html1"] as HtmlPlaceholder;
String htmlContents = html.Html;
ImagePlaceholder img = p.Placeholders["image1"] as ImagePlaceholder;
String ImageUrl = img.Href;

In SharePoint Server 2007:

PublishingPage p = null;
//Code to get to the page
LinkFieldValue linkfieldValue = p.ListItem["attachment1"]
   as LinkFieldValue;
String linkText = null;
if (null != linkfieldValue)
{
   linkText = linkfieldValue.Text;
}
String html = p.ListItem["html1"] as string;
ImageFieldValue imagefieldValue = p.ListItem["image1"] as ImageFieldValue;
String ImageUrl = null; 
if (null != imagefieldValue)
{
   ImageUrl = imagefieldValue.ImageUrl;
}

Setting Postings Values

In MCMS 2002:

Posting p=null;
String text1 = "new attachment text";
String text2 = "new html";
String text3 = "new image href";
//Code to get to the posting
AttachmentPlaceholder att = p.Placeholders["attachment1"] as 
   AttachmentPlaceholder;
att.AttachmentText = text1;
HtmlPlaceholder html = p.Placeholders["html1"] as HtmlPlaceholder;
html.Html = text2;
ImagePlaceholder img = p.Placeholders["image1"] as ImagePlaceholder;

img.Href = text3;
CmsHttpContext.Current.CommitAll();

In SharePoint Server 2007:

PublishingPage p = null;
String text1 = "new attachment text";
String text2 = "new html";
String text3 = "new image href";
//Code to get to the Page
LinkFieldValue linkfieldValue = p.ListItem["attachment1"] as 
LinkFieldValue;
if (null != linkfieldValue)
{
   linkfieldValue = new LinkFieldValue();
}
linkfieldValue.Text = text1;
p.ListItem["html1"] = text2;

ImageFieldValue img = p.ListItem["image1"] as ImageFieldValue;
if (null != img)
{
   img = new ImageFieldValue();
}
img.ImageUrl = text3;
p.ListItem["image1"] = img;
p.Update();

Navigating the Channel Hierarchy

Every MCMS site must build navigational user interface controls, and use the PAPI to transverse the site structure. SharePoint Server 2007 provides a navigation provider and some navigational controls. Additional controls are also available in Microsoft Visual Studio 2005. If you are creating navigational controls, you should consider modifying them to the Navigational Provider Model. For information about the Site Navigation API, see the ASP.NET Quickstart tutorial Using the Site Navigation API.

However, if you need to navigate the site structure in SharePoint Server 2007 as you did in MCMS 2002, it is still possible.

In MCMS 2002:

Channel root;
root = cmsContext.RootChannel;
Channel channel1;
//Move down one level 
channel1 = root.Channels["channel1"];
//Move down another level
Channel channel2;
channel2 = channel1.Channels["channel2"];
//Moving up
Channel channel3;
channel3 = channel2.Parent;

In SharePoint Server 2007:

SPWeb rootWeb = SPControl.GetContextWeb(HttpContext.Current).Site.RootWeb;
   PublishingWeb root = PublishingWeb.GetPublishingWeb(rootWeb);
   PublishingWeb pubweb1;
   // Move down one level
   pubweb1 = root.GetPublishingWebs()["pubweb1"];
   // Move down another level 
   PublishingWeb pubweb2;
   pubweb2 = pubweb1.GetPublishingWebs()["pubweb2"];
   //Moving up
   PublishingWeb pubweb3;
   pubweb3 = pubweb2.ParentPublishingWeb; 

Managing Custom Properties

Channels and postings provide a concept of custom properties. These two objects have a collection of CustomProperty objects exposed by the CustomProperties property. In MCMS, you can set custom properties by using the MCMS administrative interface or PAPI.

In SharePoint Server 2007, the "custom properties" feature is supported differently. In the case of pages, the equivalent feature is columns on pages. When postings with custom properties are migrated, this content is placed in columns on the Pages list for that site. This does not affect the user interface because not all columns have to be included in field controls that are displayed to users on a page layout.

For SPWeb objects (the SharePoint Server 2007 equivalent of channels), a AllProperties property exposes a HashTable object.

Getting Custom Property Values

In MCMS 2002:

Channel topChannel = 
   cmsContext.Searches.GetByUrl("http://localhost/woodgroove") as Channel;
//Getting custom properties from a Channel
foreach(Channel subChannel in topChannel.Channels)
{
   CustomProperty cp = subChannel.CustomProperties["property1"];
   if (cp.Value.ToLower().Equals("private"))
   {
      //Report private channels
   }

}

In SharePoint Server 2007:

To get the value of a particular custom property in a site, you can use the following code.

PublishingWeb topWeb = PublishingWeb.GetPublishingWeb(new 
   Uri("http://localhost/woodgroove"));;
//Code to set topWeb
//Getting custom properties from a SPWeb
foreach (PublishingWeb subWeb in topWeb.GetPublishingWebs())
{
   string cp = subWeb.Web.AllProperties["property1"] as string;
   if (cp.ToLower().Equals("private"))
   {
      //Report private webs
   }
}

Setting Custom Property Values

In MCMS 2002:

Channel channel;
//Code to get channel
CustomProperty cp = channel.CustomProperties["property1"];
cp.Value = "new value";

In SharePoint Server 2007:

To set the value of a particular custom property in a site, you can use the following code.

PublishingWeb publishingWeb = null;
//Code to set publishing web
publishingWeb.Web.AllProperties["property1"] = "new value";
publishingWeb.Web.Update();

Authoring Connector Templates

To use the Authoring Connector functionality in MCMS, you were required to install the Authoring Connector client and also create an Authoring Connector template in your MCMS server.

The Authoring Connector template should contain at least one OfficeHtmlPlaceholder, HtmlPlaceholder, OfficeAttachmentPlaceholder, or AttachmentPlaceholder. When a user uses the client tool to publish content, he selects a template and the conversion of the Microsoft Office Word document to HTML is handled by the Authoring Connector.

SharePoint Server 2007 provides a very similar feature called Rich Client Authoring. This feature allows users to convert documents of certain types into Web pages. You can register different document converters and configure them for the content types on your site by using the SharePoint Central Administration Pages. For more information about enabling this feature, see the Microsoft Office SharePoint Server 2007 SDK (http://msdn2.microsoft.com/en-us/ms376632(MSDN.10).aspx).

After a document converter is enabled on a content type, a convert option on the SharePoint document library for the site is available to the author. Microsoft Office dialog boxes allow the user to save a document directly to a SharePoint document library. You can also configure workflows to automate the conversion process.

For more information, see Page Publishing Using Document Converters (http://msdn2.microsoft.com/en-us/ms549211(office.12).aspx).

In SharePoint Server 2007, you do not need any specialized field types or field controls for Rich Client Authoring. This is just a setting on a per-content type basis. You can choose which HtmlField on a given content type will contain the converted document. You set up the page layout and field control to use to contain the converted HTML output with the SharePoint Central Administration pages. SharePoint Server 2007 allows you to update the converted page from the document on the document library to maintain synchronization between the document and the page.

SharePoint Server 2007 provides a default document converter for Word documents, and you can create also create your own.

You can programmatically convert files and add them to a particular page collection. The following code shows an example.

Guid GUID_FOR_CONVERTER = new Guid("{FFFFFFFF-FFFF-FFFF-FFFF-
   FFFFFFFFFFFF");
PublishingWeb publishingWeb = null;
//Code to get a particular publishing web object
SPFile sourceDocument = null;
//Code to get set the document
publishingWeb.GetPublishingPages().Add("newpage", sourceDocument, 
   GUID_FOR_CONVERTER, PageConversionPriority.High);

Also, if you have a page that was generated by converting it from a document, you can update its contents with the following code.

PublishingPage publishingPage = null;
//Code to get the page
publishingPage.UpdateContentFromSourceDocument(PageConversionPriority.
   High);

MCMS Customization

The following sections will help you understand how common customization tasks are performed in Office SharePoint Server 2007.

Custom Navigation Controls

In MCMS 2002, custom navigation controls were very common. These controls were Web User controls or Web Custom controls that used the MCMS PAPI to provide a series of links to particular channels or postings. The links rendered could vary depending on the current user or other conditions. The more common navigation controls were menu bars, breadcrumbs, and site maps.

ASP.NET 2.0 introduces a design pattern called Navigation Site Map Providers. You can configure several navigation providers for a site. Providers expose a tree structure with nodes representing the links to appear in navigation at various levels throughout the site. Display controls attach to a provider and use the data supplied to render themselves. The ASP.NET SiteMapPath control provides breadcrumb functionality by connecting directly to a site map provider. Other ASP.NET display controls, including the TreeView and Menu controls, can connect to a site map provider indirectly, through a hierarchical data source. You should rely on the ASP.NET mechanisms for navigation because they provide a standard, consistent, and easily managed solution. You can even use any third-party display controls with the site map provider and data source provided in SharePoint Server 2007. For more information, see the ASP.NET Site Navigation Overview (http://msdn2.microsoft.com/en-us/library/e468hxky.aspx).

SharePoint Server 2007 also provides a Content By Query Web Part and a Table of Contents Web Part. These two controls can be configured to present a custom selection of links. For more information, For more information, see the Microsoft Office SharePoint Server 2007 SDK (http://msdn2.microsoft.com/en-us/ms376632(MSDN.10).aspx).

If you still need custom navigation functionality that cannot be provided by the default SharePoint controls, you have a number of options. You can create new display controls or modify existing ones, and attach them to the existing provider or data source. You can also modify the behavior of the existing provider or data source, or even create your own provider or data source by using the SharePoint Server object model to traverse the site structure and return the navigation links you need.

Custom Authentication

In MCMS 2002, authentication always used Windows authentication. You could use Forms authentication and write code to create your own authentication mechanism, but these mechanisms ultimately require a user account to create the authentication ticket.

SharePoint Server 2007 takes advantage of the new ASP.NET 2.0 membership provider model. This model allows you to define your own mechanism for storing your users and passwords, and for validating them. There is no dependency on Windows user accounts.

ASP.NET 2.0 also provides standard login components, for login into the system, creating new accounts, changing passwords, and password recovery.

For more information about enabling Forms authentication and membership providers, see the Microsoft Office SharePoint Server 2007 SDK (http://msdn2.microsoft.com/en-us/ms376632(MSDN.10).aspx).

For more information about building custom providers, see Building Custom Providers for ASP.NET 2.0 Membership.

Custom Placeholder Controls

In MCMS 2002, you could use three techniques to customize your placeholder controls:

  • Write a placeholder control by deriving from the BasePlaceholderControl class.
  • Expand the functionality of existing placeholder controls by inheriting from their classes.
  • Use the SingleAttachmentPlaceholderControl or SingleImagePlaceholderControl functionality and the PresentationTemplate property.

Placeholders are mapped in SharePoint Server 2007 to field controls. These controls do not have a PresentationTemplate property, so you can customize them only by writing a field control deriving from Microsoft.SharePoint.Publishing.WebControls.BaseFieldControl.

The following example shows how to extend a RichLinkField to support movies on your pages.

namespace CMSDemo.CustomFieldControls
{
    using System;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.IO;
    using System.Globalization;
    using System.ComponentModel;

    using Microsoft.SharePoint.Publishing.WebControls;
    using Microsoft.SharePoint.Publishing.Fields;
    public class MovieSelector : BaseRichSelector
    {
        private LinkFieldValue mylclLinkValue;
        private Control mylclDisplayControl;
        private bool mylclDisplayIcon;

        #region MyRegion
        internal string getResourceUrlPath(string clientFilename, 
           bool localized)
        {
            string text1 = "";
            string text2 = "1033/";
            if (0 == string.Compare(".gif", Path.GetExtension(clientFilename), true, CultureInfo.InvariantCulture))
            {
                text1 = "IMAGES/";
                if (localized)
                {
                    text1 = text2 + text1;
                }
            }
            else if (0 == string.Compare(".js",  
               Path.GetExtension(clientFilename), true, 
               CultureInfo.InvariantCulture))
            {
                text1 = text2;
            }
            return ("http://jmassontest/_layouts/" + text1 + 
               clientFilename);
        }

        internal string getResourceUrlPath(string clientFilename)
        {
            return this.getResourceUrlPath(clientFilename, false);
        }

        #endregion

        public MovieSelector()
        {
            this.mylclLinkValue = new LinkFieldValue();
            this.mylclDisplayControl = new HtmlGenericControl("SPAN");
        }

        protected override string AssetInsertButtonImageUrl
        {
            get
            {
                return getResourceUrlPath("wmicon.GIF", true);
            }
        }

        protected override string AssetRemoveButtonImageUrl
        {
            get
            {
                return getResourceUrlPath("CMSRemoveLink.GIF");
            }
        }

        protected override string EmptyPanelPromptString
        {
            get
            {
                return "Click here to add a Windows Media Player 
                   movie file";
            }
        }

        protected override string InsertButtonText
        {
            get
            {
                return "Add Windows Media Player movie file";
            }
        }

        protected override string InsertButtonTooltip
        {
            get
            {
                return "Clever tooltip text;";
            }
        }
        public override HtmlTagValue Value
        {
            get
            {
                if (null == this.mylclLinkValue)
                {
                    this.mylclLinkValue = new LinkFieldValue();
                }
                return this.mylclLinkValue;
            }
            set
            {
                this.mylclLinkValue = value as LinkFieldValue;
            }
        }

        protected override string SelectorTypeString
        {
            get
            {
                return "Link";
            }
        }

        public override Control DisplayControl
        {
            get
            {
                string text1;
                this.mylclDisplayControl.ID = "MovieFieldDisplay";
                if (string.IsNullOrEmpty(this.Value.ToString()))
                {
                    text1 = "<A></A>";
                }
                else
                {
                    text1 = this.Value.ToString();
                }
                this.mylclDisplayControl.Controls.Clear();
                this.mylclDisplayControl.Controls.Add(new 
                   LiteralControl(text1));
                return this.mylclDisplayControl;
            }
        }

        [Browsable(true)]
        public bool DisplayIcon
        {
            get
            {
                return this.mylclDisplayIcon;
            }
            set
            {
                this.mylclDisplayIcon = value;
            }
        }


    }
    public class MovieFieldControl : RichLinkField
    {
        private MovieSelector mySelector;

        protected override Type ExpectedEditControlClassType
        {
            get
            {
                return typeof(MovieSelector);
            }
        }
        protected override string DefaultTemplateName
        {
            get
            {
                return "MovieFieldControl";
            }
        }

        protected override BaseRichSelector ChildSelectorControl
        {
            get
            {
                mySelector = base.ChildSelectorControl as MovieSelector;
                if (mySelector == null)
                {
                    mySelector = new MovieSelector();
                    mySelector.ID = base.TemplateName;
                }
                return mySelector;
            }
        }

        protected override void RenderFieldForDisplay(HtmlTextWriter 
           output)
        {
            if (null != this.ItemFieldValue)
            {
                LinkFieldValue linkVal = this.ItemFieldValue as 
                   LinkFieldValue;
                string movieUrl = linkVal.NavigateUrl;
                string movieCaption = 
                   Microsoft.SharePoint.Utilities.SPEncode.
                   HtmlEncode(linkVal.Text);

                if (movieUrl == "")
                    output.Write("(no movie specified)");
                else
                {
                    output.Write(
                            "<OBJECT classid=\"CLSID:6BF52A52-394A-11d3-
                               B153-00C04F79FAA6\"" +
                               " codebase=\"http://activex.microsoft.com/
                               activex/controls/mplayer/en/nsmp2inf.cab#
                               Version=6,0,5,0803\"" +
                            " width=\"300\" height=\"225\" >" +
                            "type=\"application/x-oleobject\" VIEWASTEXT>" 
                               + "<param name=\"Url\" value=\"" + movieUrl 
                               + "\">" +
                            "param NAME=\"autoStart\" VALUE=\"false\">" +
                            "</OBJECT><BR><div class=\"ms-smallheader\">" 
                               + movieCaption + "</div>");
                }
            }
        }
    }
}

Custom Workflows

MCMS 2002 provided a simple one-step to two-step workflow approval process based on channel security.

As an MCMS 2002 developer, you probably had to use the publishing events as a way to extend workflow functionality. Office SharePoint Server 2007 does not provide the same event model.

SharePoint Server provides extensive workflow functionality and provides default parameterized workflow templates. So if you want to create a multistep serial or parallel workflow, you can use one of the default workflow templates. Additionally, you can create your own workflow with Microsoft Office SharePoint Designer 2007 or Microsoft Visual Studio 2005. This workflow functionality is built on top of Windows Workflow Foundation (WF), for which Windows SharePoint Services V3 is the host.

Table 9 presents some common workflow extensions you had to do in MCMS 2002 and a short description of how to do these in SharePoint Server 2007.

Table 9. Common workflow extensions in MCMS 2002 and how to implement in SharePoint Server 2007

Common Work Flow Extension SharePoint Server 2007 Implementation Method
Multiple editor approval: You need a workflow involving several levels for example, author, editor, legal editor, public relations editor. Customize the multistep serial or parallel workflow template.
E-mail notification: Send an e-mail message to inform staff that postings await for their approval. Design a workflow with SharePoint Designer. In the workflow, check the needed conditions and use the action to send e-mail notifications.
Updating property values: Set up values in custom properties for certain operations. Define a field in the content type instead of custom properties. Design a workflow with SharePoint Designer. In the workflow, check the needed conditions and use the action to set the field values accordingly.
Cleaning up HTML: You need to clean out HTML imported from Word documents, removing unwanted tags. This can be done in SharePoint Server 2007 using document converters. Custom modifications to the HTML code entered by authors might still be required. Some of these changes can be done by modifying the content of fields from inside workflow actions.
Audit tracking Create a SharePoint list for auditing. Design a workflow with SharePoint Designer. Use the Create Item in List action to insert audit trails in the auditing SharePoint list you created before.

Custom Look and Feel for the Author Console

In MCMS, it was common to modify the appearance of the Web author console to make it fit with the design of your site. It was common to change console colors, fonts, texts for the actions, and action hyperlinks.

It was also common to modify the actions available on the console, such as removing, rearranging, and adding new custom actions.

Office SharePoint Server 2007 relies heavily on CSS files to customize its appearance. Look at the file in %ProgramFiles%\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033\STYLES\CORE.CSS. This file contains the styles that are used for the authoring console. For example, ms-consoleframe or ms-consolestatus. Modify these styles to change the colors and fonts of the console. For a description of its CSS styles, see the Microsoft Office SharePoint Server 2007 SDK (http://msdn2.microsoft.com/en-us/ms376632(MSDN.10).aspx).

Custom Console Actions

In MCMS you create new actions for the Web author console by inheriting from the following:

  • Microsoft.ContentManagement.WebControls.ConsoleControls.BaseAction
  • Microsoft.ContentManagement.WebControls.ConsoleControls.BasePostbackAction
  • Microsoft.ContentManagement.WebControls.ConsoleControls.BaseNewWindowAction

The mechanism for custom actions in SharePoint Server 2007 is very similar. You create new actions for the Web console by inheriting from the Microsoft.SharePoint.Publishing.WebControls.EditingMenuActions.ConsoleAction class (http://msdn2.microsoft.com/en-us/microsoft.sharepoint.publishing.webcontrols.editingmenuactions.consoleaction(office.12).aspx ) and overriding its methods.

Table 10 shows what the main element in BaseAction maps to in SharePoint Server 2007.

Table 10. How BaseAction maps to SharePoint Server 2007

BaseAction Element ConsoleAction Element
ActionJavaScript property and PerformAction method NavigateUrl property
Text property DisplayText property
Available property RequiredStates and UserRights properties

The code for the action will be in the RaisePostBackEvent property.

If you need input from the user to complete the action, you will usually have an .aspx file. This .aspx file will have input controls to get the information from the user, an accept button, and a cancel button. The click event for the accept button will contain the code for the action. The click event for the cancel button will perform the logic for aborting the action, usually returning to the URL before the action was triggered.

The following code shows the creation of pages with a specific page layout.

namespace Sample
{
    using System.Web;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Publishing;
    using Microsoft.SharePoint.Publishing.WebControls;
    using Microsoft.SharePoint.Publishing.WebControls.EditingMenuActions;
    using Microsoft.SharePoint.Utilities;

    class CreatePageWithMyLayout : ConsoleAction
    {
        public CreatePageWithMyLayout()
        {
            this.DisplayText = "Create Page with my layout";
        }
        public override string NavigateUrl
        {
            get
            {
                return ("<URL for MyLayout.aspx >" + "?CancelSource=" + 
                   SPHttpUtility.UrlKeyValueEncode(HttpContext.
                   Current.Request.Url.OriginalString));
            }
        }
        public override AuthoringStates RequiredStates
        {
            get
            {
                return (AuthoringStates.EmptyMask |
                    AuthoringStates.IsPublishingSiteTrue);
            }
        }
        public override SPBasePermissions UserRights
        {
            get
            {
                return (SPBasePermissions.EmptyMask |
                    SPBasePermissions.AddListItems);
            }
        }
    }
}

Create an .aspx file with an input field for the page name, and accept and cancel buttons. Use code like that in the Creating Postings sections in the click_event procedure of the accept button and put code to navigate to the URL in the CancelSource property of the QueryString on the click_event procedure of the cancel button.

For more information, see How to: Customize the Page Editing Toolbar (http://msdn2.microsoft.com/en-us/ms579612(office.12).aspx).

Site Deployment API Tasks

MCMS provides an option to create scripts to automate deployment tasks by using the Site Deployment API (SDAPI). The SDAPI is a COM-based programming interface.

Office SharePoint Server 2007 provides a rich deployment user interface. Most deployment scenarios can be accomplished by an IT professional by using the Web user interface, without the need for scripts. However, you can still use the object model to handle other scenarios, such as deploying content between servers that are not on the same network or writing scripts to automate common tasks.

For more information, see Deploying Content Between Servers (http://msdn2.microsoft.com/en-us/ms549024(office.12).aspx).

Conclusion

The APIs for MCMS PAPI and SharePoint Server 2007 are very different. The SharePoint Server 2007 API has a very strong SharePoint foundation. The SharePoint Server object model exposes much more functionality through Windows SharePoint Services than the original MCMS PAPI. Therefore, some basic knowledge of Windows SharePoint Services, its architecture, and the underlying SharePoint object model will be very valuable when using the object model to customize the product.

Nevertheless, there is a great parallelism between MCMS concepts and SharePoint Server 2007 concepts, and most of the coding tasks are essentially the same.

Additional Resources

This section lists a number of resources you can use to learn more about the products and technologies mentioned or used in this article.