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.
We’ve arrived at the end of ContentViewDesigner series. The last post in the series will explain how to implement a custom designer. Many of you may have noticed that while I keep talking about ContentViewDesigners, the ContentView control itself does not have a designer. In this post we are going to remedy that.
Since designers are defined as an attribute of the class, we will need to make our own custom implementation of ContentView control. This however will be a trivial thing to do. Add App_Code folder to your application if it’s not already there and then inside of it, add new class MyContentView.cs. The code for this class should look like this:
using Telerik.Cms.Engine.WebControls; |
using Telerik.Framework.Web.Design; |
namespace MyControls |
{ |
/// <summary> |
/// Enhanced ContentView control which sports a designer, unline the built-in one |
/// </summary> |
[ControlDesigner("MyControls.Design.MyContentViewDesigner, App_Code")] |
public class MyContentView : ContentView |
{ |
} |
} |
As you can see, the class itself inherits from ContentView and we do not change anything in its behavior except that we have added the ControlDesigner attribute to point to our implementation of the designer. Before we move on, let’s also add this control in Sitefinity toolbox by opening web.config and pasting following line in the telerik/csm/toolboxControls section:
<add name="My content view" section="Most popular" type="MyControls.MyContentView, App_Code" /> |
As we have declared the designer for MyContentView in the previous paragraph, now it is time to implement it. Add a class to your App_Code folder and name it MyContentViewDesigner.cs. The code for this class should look like this:
using Telerik.Cms.Engine.WebControls.Design; |
namespace MyControls.Design |
{ |
/// <summary> |
/// Control representing a designer for the ContentView control |
/// </summary> |
public class MyContentViewDesigner : ContentViewDesignerBase |
{ |
public override string DesignerTemplatePath |
{ |
get |
{ |
if (string.IsNullOrEmpty(designerTemplatePath)) |
designerTemplatePath = "~/MyTemplates/MyContentViewDesigner.ascx"; |
return designerTemplatePath; |
} |
set |
{ |
designerTemplatePath = value; |
} |
} |
string designerTemplatePath; |
} |
} |
Again, the implementation is trivial. All that we had to do is to inherit from ContentViewDesignerBase and override the designer template path.
We haven’t even started and we are almost done. The last thing that we need to do in order to get our designer up and running is to define a designer template. You may remember from the previous posts in this series that this is actually where the magic happens. Since the markup for the designer template is rather complex (in the current version, we will simplify this greatly in the versions to come) the easiest thing to do is simply to copy the markup from one of the already existing designers and then modify it to fit our needs. In this example I have copied the news designer template, located here:
~/Sitefinity/Admin/ControlTemplates/News/Design/NewsViewControlDesigner.ascx
So, as per the specified path in the previous paragraph – create a new folder in the root of your website, name it “MyTemplates” and inside of it create a new user control which you should name “MyContentViewDesigner.ascx”. In this user control paste the markup from the NewsView designer and modify it as you wish – to reflect the designer you want to have for the MyContentView control. I have done several changes and this is how my modified designer template looks when I was done:
<%@ Register Namespace="Telerik.Cms.Engine.WebControls.Design.Selectors" Assembly="Telerik.Cms.Engine" TagPrefix="sfDesignSelectors" %> |
<%@ Register Namespace="Telerik.Cms.Engine.WebControls.Design" Assembly="Telerik.Cms.Engine" TagPrefix="sfDesign" %> |
<%@ Register Namespace="Telerik.Cms.Engine.WebControls.Design.Settings" Assembly="Telerik.Cms.Engine" TagPrefix="sfDesignSettings" %> |
<div class="ctrlProps"> |
<div class="ctrlContent slidingWizard"> |
<div id="slidingWizardSteps"> |
<!-- Wizard panel 1 --> |
<div id="Panel1"> |
<h3><asp:Literal ID="Literal1" runat="server" Text="Which items to display?"></asp:Literal></h3> |
<div> |
<sfDesignSelectors:CategorySelector ID="CategorySelector" runat="server" SelectAllItemsText="Display all items" SelectSpecificItemsText="Display only items in specific categories" TypeName="Telerik.Cms.Engine.ContentManager" SelectedMethod="GetCategories" DataKey="CategoryName" /> |
</div> |
<div class="extLinks"></div> |
</div> |
<!-- end wizard panel 1 --> |
<!-- wizard panel 2 --> |
<div id="Panel2"> |
<h3><asp:Literal ID="Literal2" runat="server" Text="How to organize content items?"></asp:Literal></h3> |
<div id="itemsDisplayOptions" class="contentViewDisplayOptions"> |
<ul> |
<sfDesign:PresentationModes ID="presentationModes" runat="server"> |
<Modes> |
<sfDesign:PresentationMode ID="normalMode" runat="server" |
ModeTitle="Normal mode" |
ModeSettingsId="ModeSettings1" |
MasterTemplatePath="~/Sitefinity/ControlTemplates/Generic_Content/ContentViewItemList.ascx" |
DetailTemplatePath="~/Sitefinity/ControlTemplates/Generic_Content/ContentViewSingleItem.ascx" |
CssClass="pageListMode" |
SelectedCssClass="selectedOption pageListMode"> |
<Template> |
<asp:RadioButton ID="listPageRadio" runat="server" /> |
<p>Standard way of displaying content items...</p> |
</Template> |
</sfDesign:PresentationMode> |
</Modes> |
</sfDesign:PresentationModes> |
</ul> |
</div> |
</div> |
<!-- end wizard panel 2 --> |
<!-- wizard sliding navigation --> |
<ol class="slidingWizardNavigation"> |
<li class="previous"><a href="#" onclick="setMovement('next'); "><strong>Settings</strong> |
(optional)</a></li> |
<li class="next"><a href="#" onclick="setMovement('prev'); ">Back</a></li> |
</ol> |
<!-- end wizard sliding navigation --> |
<!-- wizard panel 3: optional settings for selected mode --> |
<div id="Panel3"> |
<h3>Content item settings</h3> |
<div id="optionalSelectedMode"> |
<sfDesign:PresentationModeSettings ID="ModeSettings1" runat="server"> |
<DetailHeaderTemplate> |
<div class="selectedModeShortDescription"> |
<h3>Selected mode</h3> |
<h4 class="selectedTitlePageList">Normal mode</h4> |
<p>Normal mode of displaying content items...</p> |
</div> |
<sfDesignSettings:PagingSetting id="pagingSetting" AllowListLimitSetting="true" DefaultListLimit="100" AllowPagingSetting="true" DefaultPageCount="20" LimitList="false" runat="server"></sfDesignSettings:PagingSetting> |
<h4>When showing single content item, display:</h4> |
<ul> |
</DetailHeaderTemplate> |
<DetailSettings> |
<sfDesignSettings:TextSetting ID="setting1" |
TargetID="Name" |
SettingTitle="Title, linking to the full article" |
AllowLabelSetting="False" |
AllowFormatSetting="False" |
AllowVisibilitySetting="False" |
TargetVisibleByDefault="True"> |
</sfDesignSettings:TextSetting> |
<sfDesignSettings:TextSetting ID="setting2" |
TargetID="Publication_Date" |
SettingTitle="Date" |
AllowLabelSetting="True" |
AllowFormatSetting="True" |
FormatType="DateTime" |
AllowVisibilitySetting="True" |
TargetVisibleByDefault="True"> |
</sfDesignSettings:TextSetting> |
<sfDesignSettings:TextSetting ID="TextSetting9" |
TargetID="content" |
SettingTitle="Content" |
AllowLabelSetting="false" |
AllowFormatSetting="false" |
AllowVisibilitySetting="True" |
TargetVisibleByDefault="True" |
> |
</sfDesignSettings:TextSetting> |
<sfDesignSettings:TextSetting ID="TextSetting2" |
TargetID="postedBy" |
SettingTitle="Author" |
AllowLabelSetting="True" |
AllowFormatSetting="True" |
FormatType="String" |
AllowVisibilitySetting="True" |
TargetVisibleByDefault="True"> |
</sfDesignSettings:TextSetting> |
</DetailSettings> |
<DetailFooterTemplate> |
</ul> |
</DetailFooterTemplate> |
<MasterHeaderTemplate> |
<h4>When showing list of items, display:</h4> |
<ul> |
</MasterHeaderTemplate> |
<MasterSettings> |
<sfDesignSettings:TextSetting ID="TextSetting1" |
TargetID="fullContent1" |
SettingTitle="Title, linking to the full article" |
AllowLabelSetting="False" |
AllowFormatSetting="False" |
AllowVisibilitySetting="False" |
TargetVisibleByDefault="True"> |
</sfDesignSettings:TextSetting> |
<sfDesignSettings:TextSetting ID="TextSetting6" |
TargetID="Publication_Date" |
SettingTitle="Date" |
AllowLabelSetting="True" |
AllowFormatSetting="True" |
AllowVisibilitySetting="True" |
TargetVisibleByDefault="True"> |
</sfDesignSettings:TextSetting> |
<sfDesignSettings:TextSetting ID="TextSetting8" |
TargetID="Author" |
SettingTitle="Author" |
AllowLabelSetting="True" |
AllowFormatSetting="False" |
AllowVisibilitySetting="True" |
TargetVisibleByDefault="True"> |
</sfDesignSettings:TextSetting> |
<sfDesignSettings:TextSetting ID="TextSetting3" |
TargetID="fullContent2" |
SettingTitle="Permanent link" |
AllowLabelSetting="True" |
AllowFormatSetting="False" |
AllowVisibilitySetting="True" |
TargetVisibleByDefault="True"> |
</sfDesignSettings:TextSetting> |
</MasterSettings> |
<MasterFooterTemplate> |
</ul> |
</MasterFooterTemplate> |
</sfDesign:PresentationModeSettings> |
</div> |
</div> |
</div> |
</div> |
</div> |
<asp:HiddenField ID="designerIsDirty" runat="server" /> |
<asp:HiddenField ID="selectedModeIdField" runat="server" /> |
<asp:HiddenField ID="selectedModeClientIdField" runat="server" /> |
<script type="text/javascript"> |
var eventsOptionsItems = document.getElementById("itemsDisplayOptions").getElementsByTagName("LI"); |
if( eventsOptionsItems ) { |
for( var i = 0; i < eventsOptionsItems.length; i++) { |
eventsOptionsItems[i].onclick = function () { |
this.getElementsByTagName("input")[0].click(); |
} |
} |
} |
</script> |
Nothing special as you can see. I’ve renamed my mode and changed some of its settings. Removed some of the settings I didn’t need, as well as the behavior setting. I believe most of the properties are self-explanatory so I won’t go into details here. You can experiment and see what happens.
The code used in this example you can download from here.
This post ends our six-part series on ContentView designers. I hope I was able to explain the most important concepts and that you will have no problems while creating or modifying your ContentViewDesigners. If you have a question, or if you think I haven’t covered something – let me know and I’ll try to do it in a timely manner. In the next posts I will be covering the FilterExpression property and ContentFilterBuilder class. I’ll talk about current implementation, motivation behind it and how will this area evolve in the future releases.
Hope you had fun with this series.
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.