Book Image

Advanced Microsoft Content Management Server Development

Book Image

Advanced Microsoft Content Management Server Development

Overview of this book

Microsoft Content Management Server 2002 is a dynamic web publishing system with which you can build websites quickly and cost-efficiently. MCMS provides the administration, authoring, and data management functionality, and you provide the website interface, logic, and workflow. Microsoft SharePoint Portal Server (SPS) also features in the book. SPS 2003 enables enterprises to deploy an intelligent portal that seamlessly connects users, teams, and knowledge so that people can take advantage of relevant information across business processes to help them work more efficiently.You've mastered the basics of MCMS, and setup your own MCMS installation. You've only scratched the surface. This book is your gateway to squeezing every penny from your investment in MCMS and SPS, and making these two applications work together to provide an outstanding richness of content delivery and easy maintainability. As a developer, the Publishing API (PAPI) is at the heart of your work with MCMS, and this book starts by taking you on the most detailed tour of the PAPI you will find anywhere. As a live example, a component that reveals the structure of your MCMS site is created, taking you through how to manage the common elements of MCMS programmatically. Getting SharePoint and MCMS to work together is the next stop in the book. You will see how to use SharePoint's search engine to search MCMS content, publish content between the two systems, and create SharePoint Web Parts to draw content from MCMS.To ease your everyday work with MCMS, there are chapters on placeholder validation, and some useful custom placeholders for common MCMS tasks, such as a date-time picker, a placeholder for multiple attachments, and a DataGrid placeholder among others. There are a number of ways to consume MCMS content from the outside world, and we look at two exciting ways here; RSS and InfoPath/Web Services. The InfoPath solution provides another interface to MCMS content that allows content authors to concentrate on content and not the presentation. The book is rounded off with a number of must-have MCMS tips and tricks. Revert a posting to a previous version Change a postingÔø???s template Build a recycle bin Deal with links to deleted resources Update a postingÔø???s properties directly from a template file Re-write ugly URLs to friendly URLs Export resource gallery items using the site deployment API (SDAPI) Configure the position and size of the Web Author Console Dialogs Get frames and IFrames to work correctly in a template file
Table of Contents (21 chapters)
Advanced Microsoft Content Management Server Development
Credits
About the Authors
About the Reviewers
Index

The Four MCMS Publishing Modes


MCMS uses four different publishing modes:

  • Published:Mode used for displaying a live version of the site

  • Staging:Mode used for staging the site using Site Stager

  • Unpublished:Mode used for displaying an unpublished version of the site (e.g. in edit site mode or in preview screens)

  • Update:Mode used for updating the site (e.g. on the authoring screen with placeholder controls in authoring mode)

Determining the Current Publishing Mode

The current mode can be found using the CmsHttpContext.Mode property. Let’s find out which mode CMS Explorer is currently using.

Above the Page_Load() event handler in the code-behind file, add the following line:

// the current CmsHttpContext
private CmsHttpContext cmsContext;

Inside the Page_Load() event, add the following code:

private void Page_Load(object sender, System.EventArgs e)
{
   cmsContext = CmsHttpContext.Current;
						if (!Page.IsPostBack)
						{
						// display the publishing mode
						lblPublishingMode.Text = "Publishing Mode: "
						+ cmsContext.Mode.ToString();
						}
}

Save and build the solution. Navigate to http://localhost/CMSExplorer/default.aspx. Notice that the label says Publishing Mode: Published. When you first view a web page on an MCMS site, you are shown the site in its Published mode. You can ignore the broken image for now as we’ll address that further along.

In Published mode, you only have access to channels and postings that have live versions and that are not marked as hidden. Channels that have expired or have their start dates set to a future date will not be available. Postings that have never been published before or are in a “Waiting For Moderator Approval”, “Waiting For Editor Approval”, “Submitted”, “Approved” or “Expired” state will also not be accessible. Obviously, for CMS Explorer to be useable, it’s got to be able to see all objects regardless of their states. In order to work with unpublished objects, we have to change the current publishing mode from Published to Unpublished, and we look at ways to accomplish this in the following sections.

Changing the MCMS Publishing Mode

There are various ways to change the MCMS publishing mode, such as by modifying the querystring parameters in the URL or by manipulating the modes via CmsHttpContext and CmsApplicationContext. Let’s take a look at each of these methods.

The Ugly URL Querystring Specifies the Publishing Mode

Let’s try a little experiment.

  1. 1. Open your browser and navigate to the http://localhost/tropicalgreen site.

  2. 2. Log in as an administrator. Click on the Switch to Edit Site button and observe the URL displayed in the browser’s address bar. It changes from a friendly URL to an ugly long URL containing the familiar querystring parameters at its tail end:

    									http://localhost/NR/exeres/71EDAD1D-9D58-4D65-8069-19DFC0114F54.htm?
    NRMODE=Unpublished
    &WBCMODE=PresentationUnpublished
    &wbc_purpose=Basic

At the same time, the Switch To Edit Site button disappears and a Switch To Live Site button appears in its place.

Now, let’s make a few changes to the querystring. With the page open in Unpublished mode:

  1. 1. Change the NRMODE querystring parameter of the ugly URL from Unpublished to Published.

  2. 2. Delete the WBCMODE querystring parameter.

  3. 3. The URL at the address bar now looks something like this:

    									http://localhost/NR/exeres/71EDAD1D-9D58-4D65-8069-19DFC0114F54.htm?
    NRMODE=Published&wbc_purpose=Basic
  4. 4. Click the Go button next to the address bar of the browser.

    Notice that the Switch To Live Site button changes back to the Switch To Edit Site button! You have effectively changed from Unpublished mode back to Published mode.

This test shows how publishing modes in MCMS can be controlled by playing around with the querystring of the generated ugly URL.

Toggling Modes with CmsHttpContext

When building your application, instead of messing around with the URLs, you can generate the querystrings for each mode on the fly using two properties of the ChannelItem object:

  • QueryStringModeUpdate for working in Update mode

  • QueryStringModeUnpublished for working in Unpublished mode

We will use this technique in CMS Explorer to switch from Published mode to Unpublished mode.

In order to get the QueryStringModeUnpublished property, we first need to get a reference to any ChannelItem. In this example, we use the root channel. If we are not in Unpublished mode, the page redirects to itself with the querystring returned by the QueryStringModeUnpublished property appended to its address. Modify the code in the Page_Load() event handler as follows:

private CmsHttpContext cmsContext;

private void Page_Load(object sender, System.EventArgs e)
{
  cmsContext = CmsHttpContext.Current;

  // Redirect if not in unpublished mode
							if (cmsContext.Mode != PublishingMode.Unpublished
							&& cmsContext.Mode != PublishingMode.Update)
							{
							string query;
							query = cmsContext.RootChannel.QueryStringModeUnpublished;
							Response.Redirect("default.aspx?" + query);
							}

  if (!Page.IsPostBack)
  {
    //Display the publishing mode
    lblPublishingMode.Text = "Publishing Mode: "
                           + cmsContext.Mode.ToString();
  }
}

Save and build the solution. Navigate to http://localhost/CMSExplorer/default.aspx again. Notice that the label now says Publishing mode: Unpublished. We have successfully toggled to Unpublished mode!

The drawback of using CmsHttpContext to toggle between modes is that it requires you to first get a reference to a ChannelItem object as well as a client redirect. For this example, we used the root channel. If the user does not have rights to the root channel, the code fails.

Note

How can I toggle to Update mode?

To toggle to Update mode, simply use the ChannelItem.QueryStringModeUpdate property instead, like so:

if (CmsContext.Mode != PublishingMode.Update)
{
   Response.Redirect("default.aspx?"
     + CmsHttpContext.Current.RootChannel.QueryStringModeUpdate);
}

Toggling Modes with CmsApplicationContext

Another popular method of toggling between modes leverages the CmsApplicationContext object. This object is typically used for stand-alone applications that run outside IIS, such as console and desktop applications. In these cases, the CmsHttpContext is meaningless and can’t be used.

You can also use the CmsApplicationContext object within a web application when you require additional CmsContext objects, especially when working with different modes. You can maintain CmsHttpContext in Published mode, and have a separate CmsApplicationContext in Update mode. Another advantage to using CmsApplicationContext is that it reduces the number of client round trips required.

We won’t be using CmsApplicationContext in the CMS Explorer application. Nevertheless, no lesson on mode switching is complete without introducing the class.

To use the CmsApplicationContext object, first create a new instance of it:

// Create a new CmsApplicationContext
CmsApplicationContext cmsContext = new CmsApplicationContext();

Unlike CmsHttpContext, CmsApplicationContext must be authenticated with the MCMS server using one of four authentication methods. Each authentication method accepts an input parameter of type PublishingMode specifying the mode you wish to work in.

  • AuthenticateAsCurrentUser

    Authenticates using the credentials of the currently logged-on user. This method does not work correctly from within a web application. It is used only when running the application outside of IIS, e.g. from a console application, because it uses the process token. For web applications, using the process token means that the currently logged on user is the user configured in the machine.config file (in IIS 5) or the application pool account (in IIS 6) instead of the user that has been authenticated in CmsHttpContext (which uses the thread token).

    To authenticate as the current user:

    // authenticate as the current user
    cmsContext.AuthenticateAsCurrentUser(PublishingMode.Unpublished);
  • AuthenticateAsGuest

    Authenticates using the guest account specified in the SCA. Works only if you have guest access turned on.

    To authenticate as the guest user:

    // authenticate as Guest user
    cmsContext.AuthenticateAsGuest(PublishingMode.Published);
  • AuthenticateAsUser

    This method accepts at least two parameters: the user ID and the password. The user ID is always in the format WinNT://domain/UserId. The password has to be passed in as a string.

    To authenticate with a specified user ID:

    // specify the user ID, password and publishing mode
    cmsContext.AuthenticateAsUser("WinNT://domain/UserId",
                                  "password",PublishingMode.Unpublished);
  • AuthenticateUsingUserHandle

    Authenticates using a Windows token by passing in the token of the currently logged on Windows user. This method has the advantage of not requiring the developer to code a password and is often used within web applications. However, if your chosen authentication mechanism is Forms Authentication, this method will not work as Windows tokens are not issued in that case.

    To authenticate with the Windows token of the currently logged on user:

    // get a Windows token of the currently logged on user
    System.Security.Principal.WindowsIdentity ident;
    ident = HttpContext.Current.User.Identity as
       System.Security.Principal.WindowsIdentity;
    
    CmsApplicationContext cmsContext = new CmsApplicationContext();
    cmsContext.AuthenticateUsingUserHandle(ident.Token,
                                     PublishingMode.Unpublished);

Once authenticated, you can use the Searches object to retrieve objects as you would with CmsHttpContext. The objects you access with CmsApplicationContext will be presented in the mode that you specify.

Adding Querystring Parameters to the URL with CmsHttpContext.PropagateParameter()

We are going to do lots of toggling between modes in our CMS Explorer application. To make things easier, we will write a helper function called PrepareUrl() that will use the CmsHttpContext object to generate a URL to change the publishing mode. The PrepareUrl() method will accept three input parameters:

  • hItem: HierarchyItem object the user has selected to work with. It could be the start container or any of its child items.

  • Mode:Publishing mode to work in. To list both published and unpublished content, we need to use Unpublished mode. To modify object property values, you need to be in Update mode.

  • pageName:Name of the dialog or page to open.

The method returns the URL, which is made up of the pageName appended with the QueryStringModeUnpublished or QueryStringModeUpdate property of the root channel. The generated querystring contains the GUID of the current channel or posting somewhere in the URL but holds no information about template galleries and resource galleries. To get around this, we add more information by introducing two additional parameters:

  • CMSObject:Contains a string with value “Templates” or “Resources”.

  • CMSObjectGuid:Stores the GUID of the template gallery or resource gallery selected by the user as the start container.

The CmsHttpContext.PropagateParameter() method inserts these two parameters into all URLs generated by MCMS within the session. Add PrepareUrl() directly below the Page_Load() event handler:

private string PrepareUrl(HierarchyItem hItem, PublishingMode mode,
                          string pageName)
{
  string url = "";
  if (hItem != null)
  {
    string cmsObject = "";
    if (hItem is TemplateGallery)
    {
      cmsObject = "Templates";
    }
    else if (hItem is ResourceGallery)
    {
      cmsObject = "Resources";
    }
    cmsContext.PropagateParameter("CMSObject",cmsObject);
    cmsContext.PropagateParameter("CMSObjectGuid",
                         HttpUtility.UrlEncode(hItem.Guid));
    url = pageName + "?";

    if (mode == PublishingMode.Unpublished)
    {
      url += cmsContext.RootChannel.QueryStringModeUnpublished;
    }
    else if (mode == PublishingMode.Update)
    {
      url += cmsContext.RootChannel.QueryStringModeUpdate;
    }
  }
  return url;
}

The next time a URL is requested from the ChannelItem.Url property (or any of the properties that generate URLs), the querystring includes the two additional parameters:

http://localhost/cmsexplorer/default.aspx?
CMSObject=Templates&

NRMODE=Unpublished&
FRAMELESS=true&
CMSObjectGuid=%7b4D1912B-9DD3-11D1-B44E-
							006097071264%7d&NRNODEGUID=%7bE4D19123-9DD3-11D1-B44E-006097071264%7d
						

PrepareUrl() will be used to generate URLs later as we work through the CMS Explorer code.