More in this section
Categories
Bloggers
Blogs RSS feed

Introducing PageTitleMode for ModuleBuilder DynamicContentView

by User Not Found

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

17 comments

Leave a comment
  1. Lian Lee Jul 24, 2012
    Nice post , but could you provide more information about the widget performance. 
          1. How many database queries it makes 
          2. How much time it takes to render a page with this widget without Open Access cache and output cache.
          3.  How it is going to perform if you have 20 widgets like this one ? 
  2. MONIKA Jun 04, 2018
  3. MONIKA Jun 04, 2018
    Wow i can say that this is another great article as expected of this blog.Bookmarked this site..Accident lawyer Boston
  4. MONIKA Jun 04, 2018
    The website is looking bit flashy and it catches the visitors eyes. Design is pretty simple and a good user friendly interface.buy cryptocurrencies offshore
  5. MONIKA Jun 04, 2018
    Hi! Thanks for the great information you havr provided! You have touched on crucuial points!pakej percutian
  6. MONIKA Jun 04, 2018
    I appreciated your work very thanksgenerator maintenance
  7. MONIKA Jun 06, 2018
    For over 10 years, Hair Restoration Laboratories has developed and offered to men and women the most effective dht blocking shampoos and conditioners to help reverse hair loss and regrow stronger, thicker and healthier hair.Dht blocker shampoo
  8. MONIKA Jun 07, 2018
    I found that site very usefull and this survey is very cirious, I ' ve never seen a blog that demand a survey for this actions, very curious...Detectives España
  9. MONIKA Jun 08, 2018
    I have recently started a blog, the info you provide on this site has helped me greatly. Thanks for all of your time & work.Zwembaden
  10. MONIKA Jun 09, 2018
    No doubt this is an excellent post I got a lot of knowledge after reading good luck. Theme of blog is excellent there is almost everything to read, Brilliant post.print t shirt
  11. MONIKA Jun 11, 2018
    Nice to be visiting your blog again, it has been months for me. Well this article that i’ve been waited for so long. I need this article to complete my assignment in the college, and it has same topic with your article. Thanks, great share.Lynnwood, WA- Near
  12. MONIKA Jun 14, 2018
    I would like to thank you for the efforts you have made in writing this article. I am hoping the same best work from you in the future as well..curtida no instagram
  13. Monika Jun 21, 2018
    For over 10 years, Hair Restoration Laboratories has developed and offered to men and women the most effective DHT blocking hair loss shampoos and conditioners to help reverse hair loss and regrow hair.Reasons for hair loss
  14. Monika Jun 22, 2018
    Thank you for some other informative blog. Where else could I get that type of information written in such an ideal means? I have a mission that I’m just now working on, and I have been at the look out for such information.visit homepage
  15. Richard E. Bailey Jun 25, 2018
    Nice to be visiting your blog again, it has been months for me. Well this article that i've been waited for so long. I need this article to complete my assignment in the college, and it has same topic with your article. Thanks, great share.Detectives Madrid
  16. detective Jul 14, 2018
    Your blog provided us with valuable information to work with. Each & every tips of your post are awesome. Thanks a lot for sharing. Keep blogging..detectives Madrid
  17. Annett Dresdner Jul 18, 2018
    Nice to be visiting your blog again, it has been months for me. Well this article that i’ve been waited for so long. I need this article to complete my assignment in the college, and it has same topic with your article. Thanks, great share.Minoxidil dht Blockers

    Leave a comment