Introducing PageTitleMode for ModuleBuilder DynamicContentView

Introducing PageTitleMode for ModuleBuilder DynamicContentView

Posted on July 24, 2012 0 Comments

The content you're reading is getting on in years
This post is on the older side and its content may be out of date.
Be sure to visit our blogs homepage for our latest news, updates and information.

Some of you have shown particular interest in controlling the Page title behavior when viewing ModuleBuilder items. While we have this task on our to-do list, we decided that it'd be good to provide you with a solution before the actual feature implementation.

With this blog post we're going to show you how you can:

1. Create a customized DynamicContentView widget, which inherits from the default one and implement your own behavior

2. Automatically configure the custom DynamicContentView to work with a particular Module Builder type

3. Implement the PageTitleMode logic as in the current ContentView widgets

 

Please find the detailed steps below:

 

1. Creating the customized DynamicContentView widget

 To extend the default DynamicContentView with our own logic we can simply create a new class in our project and inherit from Telerik.Sitefinity.DynamicModules.Web.UI.Frontend.DynamicContentView. For this particular example we do not need to change any of the default designer or definition so just by doing:

namespace SitefinityWebApp
{
    public class DCVCustom : DynamicContentView
    {
    }
}

we already have a working DynamicContentView.

 

2. Configuring the new widget to work with a particular Module Builder module

One thing worth noting, is that unlike ContentView widgets, where you have a separate widget for each content type (e.g. NewsView, EventsView etc.) with Module Builder all modules automatically register an instance of the same control type - DynamicContentView.

How do we get a readily configured widget that works with our specific type then? It's actually very easy - we have exposed three properties that need to be set in the widget registration in the toolbox, that allow you to differentiate between the different Module Builder created modules.

If we take for example one of my modules created with Module Builder - "Sections", here's the widget registration in the ToolboxesConfig.config:

<add enabled="True" type="Telerik.Sitefinity.DynamicModules.Web.UI.Frontend.DynamicContentView, Telerik.Sitefinity, Version=5.0.2500.0, Culture=neutral, PublicKeyToken=b28c218413bdf563" title="Sections" cssClass="sfNewsViewIcn" moduleName="DynamicModule" DynamicContentTypeName="Telerik.Sitefinity.DynamicTypes.Model.Sections.Section" DefaultMasterTemplateKey="d7632471-8a02-4d3f-89ad-c0268eed5735" DefaultDetailTemplateKey="22affc46-7b7e-480e-9245-d085cdea2e8a" visibilityMode="None" name="Telerik.Sitefinity.DynamicTypes.Model.Sections.Section" />
 You can notice that his widget registration differs slightly with the DynamicContentTypeName, DefaultMasterTemplateKey, and DefaultDetailTemplateKey properties. The DynamicContentTypeName represents your Module Builder module type, while the latter DefaultMasterTemplateKey and DefaultDetailTemplateKey  are just the IDs of your List and Single Item templates. So for the purposes of registering my custom DynamicContentView in the toolbox, and make it work with a particular Module Builder type, all I need to do is copy these three properties in my widget registration. Finally here's what my custom widget which will work again with the "Sections" Module Builder module looks like:
<add enabled="True" type="SitefinityWebApp.DCVCustom" title="DCVCustom" description="DCVCustom" DynamicContentTypeName="Telerik.Sitefinity.DynamicTypes.Model.Sections.Section" DefaultMasterTemplateKey="d7632471-8a02-4d3f-89ad-c0268eed5735" DefaultDetailTemplateKey="22affc46-7b7e-480e-9245-d085cdea2e8a"  visibilityMode="None" name="DCVCustom" />

 

3. Implementing  PageTitleMode for our widget

As you probably know we already can control the Page title behavior in our Content modules - this is controlled by the PageTitleMode property of each ContentView widget.

The PageTitleMode property can be set to: Replace, DoNotSet, and Append; which pretty much explains what ti does - it can replace the current page title with the title of the currently displayed Module Builder item, or alternatively Append it to the title. Of course you have the choice of not changing the title at all, by selecting DoNotSet.

 

First we need to expose a public property to hold our selection for PageTitleMode :

# region Properties
     
       public PageTitleModes PageTitleModeInternal { get; set; }
       public DynamicContent DetailItem { get; set; }
       /// <summary>
       /// Defines identifiers that indicate if and how the page title should be set.
       /// </summary>
       public enum PageTitleModes
       {
           /// <summary>
           /// Indicates that the page title should be replaced by the item title.
           /// </summary>
           Replace,
           /// <summary>
           /// Indicates that the page title should not be altered.
           /// </summary>
           DoNotSet,
           /// <summary>
           /// Indicates that the item title should be appended to the page title.
           /// </summary>
           Append
       };
       # endregion

We can then use this selection to determine what shall we do with the Page title:

protected virtual void ResolvePageTitle()
       {
           if (this.DetailItem == null || this.Page == null)
               return;
           if (this.PageTitleModeInternal == PageTitleModes.DoNotSet)
               return;
           DynamicContent cnt = this.DetailItem as DynamicContent;
           if (cnt == null)
               return;
           if (this.IsSingleItem())
           {
               var title = cnt.GetValue<String>("Title");
               switch (this.PageTitleModeInternal)
               {
                   case PageTitleModes.Append:
                       if (title != null)
                           this.Page.Title = String.Format("{0} {1}", this.Page.Title, title);
                       break;
                   case PageTitleModes.Replace:
                       if (title != null)
                           this.Page.Title = title;
                       else
                           this.Page.Title = "";
                       break;
               }
           }
       }

As you have noticed from the above method, we would need to determine two things in order for this functionality to work correctly:

 

1. Check if the control is displaying a single item - this can be achieved very easily, as we already have an out of the box logic for doing this - the IsSingleItem() method of the base class DynamicContentView will return true or false, upon which we can do our conditional logic when the widget is displaying a single item.

 

2. Once we've determined a single item being displayed, we need to actually get it and retrieve its Title property, so we can operate with it:

protected void SetSingleItem()
        {
            if (this.DetailViewDefinition.DataItemId != Guid.Empty)
            {
                this.DetailItem = this.DynamicManager.GetDataItem(this.DynamicContentType, this.DetailViewDefinition.DataItemId);
            }
            var urlParameters = this.GetUrlParameters();
            if (urlParameters != null && urlParameters.Length != 0)
            {
                var redirectUrl = "";
                var item = this.DynamicManager.Provider.GetItemFromUrl(this.DynamicContentType, this.GetUrlParameterString(true), out redirectUrl) as DynamicContent;
                if (item != null && item.GetType() == this.DynamicContentType)
                {
                    if (!String.IsNullOrEmpty(this.GetUrlParameterString(false)))
                    {
                        var matches = Regex.Matches(this.GetUrlParameterString(false), widgetNameRegularExpression);
                        if ((matches.Count == 1 && matches[0].Groups["urlPrefix"].Value == this.UrlKeyPrefix)
                            || (matches.Count == 0 && String.IsNullOrEmpty(this.UrlKeyPrefix)))
                        {
                            this.DetailItem = item;
                            RouteHelper.SetUrlParametersResolved();
                        }
                    }
                }
            }
        }

In the above method we simply set the DetailItem public property of our custom widget, which we are using in the ResolvePageTitle() to retrieve the item Title and work with it.

 

Finally our class should look like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Telerik.Sitefinity.DynamicModules.Web.UI.Frontend;
using Telerik.Sitefinity.Model;
using Telerik.Sitefinity.DynamicModules.Model;
using System.Text.RegularExpressions;
using Telerik.Sitefinity.Web;
using System.Web.UI;
namespace SitefinityWebApp
{
    public class DCVCustom : DynamicContentView
    {
        # region Properties
      
        public PageTitleModes PageTitleModeInternal { get; set; }
        public DynamicContent DetailItem { get; set; }
        /// <summary>
        /// Defines identifiers that indicate if and how the page title should be set.
        /// </summary>
        public enum PageTitleModes
        {
            /// <summary>
            /// Indicates that the page title should be replaced by the item title.
            /// </summary>
            Replace,
            /// <summary>
            /// Indicates that the page title should not be altered.
            /// </summary>
            DoNotSet,
            /// <summary>
            /// Indicates that the item title should be appended to the page title.
            /// </summary>
            Append
        };
        # endregion
        #region Methods
       
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            this.SetSingleItem();
            this.ResolvePageTitle();
        }
        protected virtual void ResolvePageTitle()
        {
            if (this.DetailItem == null || this.Page == null)
                return;
            if (this.PageTitleModeInternal == PageTitleModes.DoNotSet)
                return;
            DynamicContent cnt = this.DetailItem as DynamicContent;
            if (cnt == null)
                return;
            if (this.IsSingleItem())
            {
                var title = cnt.GetValue<String>("Title");
                switch (this.PageTitleModeInternal)
                {
                    case PageTitleModes.Append:
                        if (title != null)
                            this.Page.Title = String.Format("{0} {1}", this.Page.Title, title);
                        break;
                    case PageTitleModes.Replace:
                        if (title != null)
                            this.Page.Title = title;
                        else
                            this.Page.Title = "";
                        break;
                }
            }
        }
        protected void SetSingleItem()
        {
            if (this.DetailViewDefinition.DataItemId != Guid.Empty)
            {
                this.DetailItem = this.DynamicManager.GetDataItem(this.DynamicContentType, this.DetailViewDefinition.DataItemId);
            }
            var urlParameters = this.GetUrlParameters();
            if (urlParameters != null && urlParameters.Length != 0)
            {
                var redirectUrl = "";
                var item = this.DynamicManager.Provider.GetItemFromUrl(this.DynamicContentType, this.GetUrlParameterString(true), out redirectUrl) as DynamicContent;
                if (item != null && item.GetType() == this.DynamicContentType)
                {
                    if (!String.IsNullOrEmpty(this.GetUrlParameterString(false)))
                    {
                        var matches = Regex.Matches(this.GetUrlParameterString(false), widgetNameRegularExpression);
                        if ((matches.Count == 1 && matches[0].Groups["urlPrefix"].Value == this.UrlKeyPrefix)
                            || (matches.Count == 0 && String.IsNullOrEmpty(this.UrlKeyPrefix)))
                        {
                            this.DetailItem = item;
                            RouteHelper.SetUrlParametersResolved();
                        }
                    }
                }
            }
        }
        #endregion
        #region Constants
        private const string widgetNameRegularExpression = @"/!(?<urlPrefix>[a-zA-Z0-9_\-]+)/.*";
        #endregion
    }
}

 

For your convenience I'm attaching an archive of the class to this blog post - CustomDynamicContentView , so you can directly include it in your solution and use it.

I hope you found the blog post useful. Any comments and suggestions are highly appreciated.

CustomDynamicContentView

progress-logo

The Progress Team

View all posts from The Progress Team on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.

Comments

Comments are disabled in preview mode.
Topics

Sitefinity Training and Certification Now Available.

Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.

Learn More
Latest Stories
in Your Inbox

Subscribe to get all the news, info and tutorials you need to build better business apps and sites

Loading animation