Click here to Skip to main content
15,909,091 members
Articles / Web Development / ASP.NET
Article

MCMS User Selectable Content

Rate me:
Please Sign up or sign in to vote.
4.40/5 (4 votes)
27 Oct 20054 min read 31.3K   261   18   2
Discusses how to allow selectable content.

Introduction

I have worked on a project that requires a different disclaimer for each posting category, because each posting describes a product that the company is offering. Within these offerings, the disclaimers are the same but otherwise different for other types of offerings. Therefore disclaimer contents are also shared within the same offering. So the solution is, create a set of templates that provide a list of available disclaimers that the content author can select from. When the author saves the posting, the selected disclaimer will be saved as part of the posting. This challenging task requires some tricky design. First we need an object that will self render with a default disclaimer and then it needs to handle different posting stages like published, unpublished, edit, new, preview and save modes. The sample code can be reused for any kind of contents not just disclaimers. Thanks to Stefan Goßner for providing a shared content custom control that makes this possible.

Hosting Page Screenshot

Disclaimer Control

I have included an SDO in the source zipped file with a list of disclaimers that you can import into your Woodgrove channel. The disclaimer channel is hidden when published. The list also consists of a default disclaimer. The disclaimer control when first created defaults to the _defaultdisclaimer content. The disclaimer control is a user control that has a dropdown list box and a RenderPlaceholderServerControl from Stefan Goßner articles found in the Gotdotnet web site. The RenderPlaceholderServerControl is used for shared content.

The first thing the disclaimer user control does is determine which stage the posting is in and then load the dropdown list from the disclaimer channel when it is in edit mode. The most difficult part is figuring out the stage and what to render for that stage.

disclaimerbox.ascx.cs

C#
private void Page_Load(object sender, System.EventArgs e)
{
    if (!Page.IsPostBack)
    {
        ViewState["IsDisclaimerChanged"] = "False";
    }
    switch (mode)
    {
        case WebAuthorContextMode.PresentationPublished:
        case WebAuthorContextMode.PresentationUnpublished:
        case WebAuthorContextMode.AuthoringPreview:
            Disclaimerdropdown.Items.Clear();
            PublishedModeDisclaimer();
            break;
        case WebAuthorContextMode.AuthoringReedit:
        case WebAuthorContextMode.AuthoringNew:
            if (Disclaimerdropdown.Items.Count == 0)
            {
                FillDropdown();
                if (CmsHttpContext.Current.Posting.CustomProperties[
                                "Disclaimer"].Value != string.Empty)
                    Disclaimerdropdown.SelectedValue = 
                      CmsHttpContext.Current.Posting.CustomProperties[
                                                  "Disclaimer"].Value;
            }
              EditModeDisclaimer();
            break;
        default:
            Disclaimerdropdown.Items.Clear();
            PublishedModeDisclaimer();
            break;
    }
}

During the editing process saving the posting with the selected disclaimer is the most critical step. To save the disclaimer together with the posting, you must add an event handler. This is not just any event handler but a content context event hander. The disclaimer content itself does not get saved together with the posting but the custom property "Disclaimer" on the posting gets saved.

C#
override protected void OnInit(EventArgs e)
{
    // CODEGEN: This call is required by the ASP.NET Web Form Designer.
    WebAuthorContext.Current.SavePostingEvent += 
      new WebAuthorPostingEventHandler( this.OnSavePosting );
    InitializeComponent();
    base.OnInit(e);
}

private void OnSavePosting(object sender, WebAuthorPostingEventArgs e)
{
    try
    {
        if (e.Posting.CustomProperties["Disclaimer"] != null)
        {
            if ((string) ViewState["IsDisclaimerChanged"] == "True")
            {
                CustomProperty oProperty = 
                       e.Posting.CustomProperties["Disclaimer"];
                oProperty.Value = Disclaimerdropdown.SelectedItem.Value;
                ViewState["IsDisclaimerChanged"] = "False";
            }
        }
    }
    catch (Exception ex)
    {
        throw new Exception("Failed to update disclaimer custom property", ex);
    }
}

The event "WebAuthorContext.Current.SavePostingEvent" is executed when the user click on the Save or "Save & exit" link on the console menu. I also have a view state value to keep track of the modify state. The template that hosts the disclaimer user control must have a custom property named "Disclaimer" in order for this to work. The value saved in the custom property is what determines what disclaimer is loaded during the page load. The PublishedModeDisclaimer() method looks at the custom property value and sets the path disclaimer path for the RenderPlaceholderServerControl to load.

Note: I save the disclaimer posting name in the custom property but you could use a GUID instead and use the GUID to reload the posting on page load.

C#
private void PublishedModeDisclaimer()
{
    try
    {
        disclaimerpaneledit.Visible = false;
        if (CmsHttpContext.Current.Posting.CustomProperties["Disclaimer"] != null)
        {
            if (CmsHttpContext.Current.Posting.CustomProperties[
                             "Disclaimer"].Value == string.Empty)
            {
                Channel oChannel = (Channel)
                  CmsHttpContext.Current.RootChannel.GetByRelativePath(
                                            "WoodgroveNet/Disclaimer");
                PostingCollection oPostings = oChannel.Postings;
                oPostings.SortByDisplayName(true);
                RenderPhServerControl1.PostingPath = 
                   "/Channels/WoodgroveNet/Disclaimer/" + oPostings[0].Name;
            }
            else
            {
                RenderPhServerControl1.PostingPath = 
                  "/Channels/WoodgroveNet/Disclaimer/" 
                  + CmsHttpContext.Current.Posting.CustomProperties[
                                                "Disclaimer"].Value;
            }
        }
    }
    catch (Exception ex)
    {
        throw new Exception("Failed to set disclaimer in published mode", ex);
    }
}

For the disclaimer box, the RenderPlaceholderServerControl default placeholder name is "Content". The default disclaimer custom property value is "_defaultdisclaimer". The disclaimer postings are created with the Shared Content template in the disclaimer channel. You can make the posting path move dynamically by using the ApplicationPath or something stored in the Web.Config file. I chose to hard code the path because it's easier.

Disclaimer Postings

Note: RenderPlaceholderServerControl posting path is hard-coded with "/Channels/WoodgroveNet/Disclaimer/" + whatever disclaimer posting the user selected.

The posting path gets set during the Page_Load event and when the user changes the dropdown selection, the path gets set to the selected posting. If no disclaimer were selected then the default disclaimer is selected as the default. The disclaimer posting must be created first before they can get selected in the host posting. The host posting can be any template with the disclaimer user control. Saving the host posting will only save the custom property "Disclaimer" with the name of the disclaimer selected.

Posting

As you can see in the image above the hosting page "TestDisclaimer" custom property "Disclaimer" is set to "Disclaimer1".

I have included all this in the source zipped file together with the SDO file.

Hosting Template

The hosting template is just any template with the disclaimer box user control on the page. In this example, the home template is copied and the disclaimer box user control on the template is added.

TestDisclaimer.aspx

HTML
<tr>
    <td>
        <uc1:disclaimerbox id="Disclaimerbox1" runat="server"></uc1:disclaimerbox>
    </td>
</tr>

Most of the coding is done in the disclamerbox user control so the host page template doesn't have much to do. The only requirement for this disclaimer to work is that the hosting template must have a custom property named "Disclaimer". The host posting in edit mode will have the disclaimer dropdown box and an edit control link and the disclaimer text content. In live site mode, only the disclaimer text content is visible.

Conclusion

You can make portions of your posting user selectable and dynamic. Users can easily switch between contents by using a list of sub postings that are pre-approved by editors. You can use this technique to control what the user can show in a particular posting.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior) LEN Associates Inc.
United States United States
Years of software consulting and software development using Microsoft development products such as Microsoft Content Management System, SQL Server Reporting Service, ASP.Net C# VB.Net, HTML and javascript web development, Visual Studio add-on development, C++ MFC/ATL and COM+ development, and ActiveX components.

Comments and Discussions

 
General[Message Removed] Pin
immetoz4-Oct-08 2:08
immetoz4-Oct-08 2:08 
GeneralContent Management Nightmare Pin
L Viljoen14-Feb-07 1:53
professionalL Viljoen14-Feb-07 1:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.