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"
/>
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.
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.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites
Progress collects the Personal Information set out in our Privacy Policy and the Supplemental Privacy notice for residents of California and other US States and uses it for the purposes stated in that policy.
You can also ask us not to share your Personal Information to third parties here: Do Not Sell or Share My Info
We see that you have already chosen to receive marketing materials from us. If you wish to change this at any time you may do so by clicking here.
Thank you for your continued interest in Progress. Based on either your previous activity on our websites or our ongoing relationship, we will keep you updated on our products, solutions, services, company news and events. If you decide that you want to be removed from our mailing lists at any time, you can change your contact preferences by clicking here.