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. Open your browser and navigate to the
http://localhost/tropicalgreen
site.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. Change the
NRMODE
querystring parameter of the ugly URL fromUnpublished
toPublished
.2. Delete the
WBCMODE
querystring parameter.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=Basic4. 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 toPublished
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 inUpdate
modeQueryStringModeUnpublished
for working inUnpublished
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 inCmsHttpContext
(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 useUnpublished
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.