Sitefinity CMS

Example: Extending Content View Control Send comments on this topic.
See Also
Developing with Sitefinity > Controls > Extending Built-in Controls in Sitefinity > Example: Extending Content View Control

Glossary Item Box

ContentView control is a base public control used by all Generic Content based modules. Examples of specific implementations of this control are BlogPosts, NewsView and EventsView. ContentView control has been specifically designed to be extended (though it can be used as a standalone control).

 

Many times, you will not be satisfied with the way some of the Generic Content public controls behave and you will want to modify them or provide completely new implementations. For example, if you want to just slightly modify the way the EventsView control behaves, you can implement a new control by inheriting it. On the other hand, if you wish to provide a completely new implementation of a public control for displaying events, you will be best off implementing a new control by inheriting ContentView control.

In this topic we will demonstrate how to create a custom implementation of the ContentView control.

Scenario

We are going to add a custom meta-field to the Generic Content module, named "Author_Picture". In this meta-field we want authors to enter the URL of their picture. On the public side we want to have an image control whose ImageUrl property will be equal to the value of the Author_Picture meta-field. In addition to this, we want to be able to filter Generic Content items by the author name.

 

Problems

First problem we are facing is how to use meta-field value as ImageUrl property. Namely, the standard ContentView control will automatically set the Text property of all controls whose ID is equal to the meta-field key. But, how can we set the ImageUrl property?

Second problem is that standard ContentView control does not allow filtering of Content Items by Author.

 

Solution

To accomplish our goals we are going to create a new public control based on ContentView. We will name it CustomContentView. On this control we are going to implement functionality which will set the ImageUrl property of  "Author_Picture" control in the template to the value of "Author_Picture" meta-field.
Secondly, we will implement AuthorFilter property to let users filter content items by Author. Then we will implement this filter.

Download the Sample Code from here.

 

Step by Step Instructions

PART 1 : Adding New Meta Field to Generic Content Module

  1. Register new meta field for Generic Content module in web.config:
    web.config Copy Code
    <metaFields>
     

     
    <add key="Generic_Content.Author_Picture" valueType="ShortText"  
     
    visible="True" searchable="False" sortable="False" defaultValue="" />
  2. Add user interface controls for inserting the value of Author_Picture meta-field in the following template (template for inserting new Generic Content items):
                    ~/Sitefinity/Admin/ControlTemplates/Generic_Content/ControlPanelInsert.ascx
    Add the following markup right after the markup for the Author meta-field:  
    ControlPanelInsert.ascx Copy Code
    <li>
     
    <asp:Label ID="Label5" AssociatedControlID="Author_Picture" runat="server">
     
    <asp:Literal ID="Literal7" runat="server" Text="Author picture">   
     
    </asp:Literal>
     
    <em id="Em2" runat="server"></em></asp:Label>
     
    <asp:TextBox ID="Author_Picture" runat="server"></asp:TextBox>
    </
    li>
  3. Add user interface controls for editing the value of Author_Picture meta-field in the following template (template for editing existing Generic Content item)
                    ~/Sitefinity/Admin/ControlTemplates/Generic_Content/ControlPanelInsert.ascx
    Add the following markup right after the markup for the Author meta-field:

    ControlPanelInsert.ascx Copy Code
    <li>
     
    <asp:Label ID="Label5" AssociatedControlID="Author_Picture" runat="server">
     
    <asp:Literal ID="Literal7" runat="server" Text="Author picture">
     
    </asp:Literal>
     
    <em id="Em2" runat="server"></em></asp:Label>
     
    <asp:TextBox ID="Author_Picture" runat="server"></asp:TextBox>
    </
    li>
  4. Add two Generic Content items and specify the Author URL to an existing image for each of them.

     

 

PART 2 : Creating a New ContentView Based Control Project

  1. Open your Sitefinity Web site in Visual Studio.
  2. Add new C# class library project to Sitefinity. Name the project SampleControl.
  3. Remove the default Class1.cs file.
  4. Add new class to the project and name it CustomContentView.cs
  5. Add reference to System.Web namespace: right-click on the project in Solution Explorer, select "Add reference", in the .NET tab find System.Web and add it.
  6. Add reference to System.Configuration namespace: right-click on the project in Solution Explorer, select "Add reference", in the .NET tab find System.Configuration and add it.
  7. Add reference to Telerik.Cms.Engine project: right-click on the project in Solution Explorer, select "Add reference", select "Browse" tab, browse to the bin folder of your Web site, find Telerik.Cms.Engine.dll and add it.
  8. Add reference to Telerik.Framework project: right-click on the project in Solution Explorer, select "Add reference", select "Browse" tab, browse to the bin folder of your Web site, find Telerik.Framework.dll and add it.

 

PART 3: Creating User Interface Templates for Your Control

Sitefinity uses templates for all of its controls and it is good to follow that pattern, especially when extending existing controls. For our CustomContentView control we will need to create two templates:

  • Item List template - for displaying list of content items
  • Single Item template - for displaying a single content item)


Since we are extending the ContentView control, we don’t need to build these templates from scratch. We will simply duplicate existing ContentView control templates and modify them to fit our needs.

  1. Create a new folder in your Web site and name it CustomContentView. This should be the path of a folder:
            ~/Sitefinity/ControlTemplates/CustomContentView
  2. Copy the following files to the folder created in previous step:
  3. Item List template
          ~/Sitefinity/ControlTemplates/Generic_Content/ContentViewItemList.ascx
  4. Single Item template
          ~/Sitefinity/ControlTemplates/Generic_Content/ContentViewSingleItem.ascx
  5. Add App_LocalResources folder to the folder created in step 1 - right-click on the folder to which you want to add it, select "Add ASP.NET Folder" and finally select "App_LocalResources". This folder will contain localization resources for our template.
    This is a necessary step, since all Sitefinity templates support localization and an exception will be thrown if resources do not exist.
  6. Copy the following files:
            ~/Sitefinity/ControlTemplates/Generic_Content/App_LocalResources/ContentViewItemList.ascx.resx
            ~/Sitefinity/ControlTemplates/Generic_Content/App_LocalResources/ContentViewSingleItem.ascx.resx
    to this folder:
            ~/Sitefinity/ControlTemplates/CustomContentView/App_LocalResources
  7. Open the newly-created Item List template for CustomContentView control:
            ~/Sitefinity/ControlTemplates/Generic_Content/ContentViewItemList.ascx
    and add Image control that will display the picture of the author (the picture of the author will be visible when Content Items are displayed as a list):
    ContentViewItemList.ascx Copy Code
    <asp:Image ID="Author_Picture" runat="server" />
  8. Open the newly-created Single Item template for CustomContentView control:
            ~/Sitefinity/ControlTemplates/Generic_Content/ContentViewSingleItem.ascx
    and add Image control that will display the picture of the author (the picture of the author will be visible when single Content Item is displayed):
    ContentViewSingleItem.ascx Copy Code
    <asp:Image ID="Author_Picture" runat="server" />
  9.  

    PART 4: Implementing a CustomContentView Control

    1. Open the CustomContentView.cs file in the project you have created in PART 2.
    2. Override the ItemListTemplatePath property to provide a new default value (pointing to the template we have created in PART 3):
      CustomContentView.cs Copy Code
      public override string ItemListTemplatePath
      {
       get
       {
          
      object obj = this.ViewState["ItemListTemplatePath"];
          
      if (obj != null)
             
      return (string)obj;
          
      // otherwise return default path of the ItemList Template. This should  
          
      // be the path of the new template we have created
          
      return  "~/Sitefinity/ControlTemplates/CustomContentView/ContentViewItemList.ascx";
       }
       set
       {
          
      this.ViewState["ItemListTemplatePath"] = value;
       }
      }
    3. Override the SingleItemTemplate path property to provide a new default value (pointing to the template we have created in PART 3):

      CustomContentView.cs Copy Code
      public override string SingleItemTemplatePath
      {
       get
       {
          
      object obj = this.ViewState["SingleItemTemplatePath"];
          
      if (obj != null)
              
      return (string)obj;
          
      // otherwise return default path of the SingleItem Template. This should
          
      // be the path of the new template we have created
          
      return "~/Sitefinity/ControlTemplates/CustomContentView/ContentViewSingleItem.ascx";
       }
       set
       {
          
      this.ViewState["SingleItemTemplatePath"] = value;
       }
      }
    4. Implement the new property “AuthorFilter”. This property will hold the name of the author by which Content Items will be filtered. If this property is an empty string, filter won’t be applied and we will display all ContentItems regardless of the Author.
      CustomContentView.cs Copy Code
      public string AuthorFilter
      {
        get
        {
           
      object obj = this.ViewState["AuthorFilter"];
           
      if (obj != null)
               
      return (string)obj;
           
      return String.Empty;
        }
        set
        {
           
      this.ViewState["AuthorFilter"] = value;
        }
      }
    5. Override SetItemMetadata method so that we can implement setting of the ImageUrl property for the "Author_Picture" meta-field:
      CustomContentView.cs Copy Code
      protected override void SetItemMetadata(System.Web.UI.Control itemContainer, Telerik.Cms.Engine.IContent contentItem)
      {
        
      // first let's call the base implementation of the SetItemMetadata, so
        
      // that it fills the values of all fields it can
        
      base.SetItemMetadata(itemContainer, contentItem);

       
      // now let's apply our own custom logic for the Author_Picture meta field
             
       
      // first we need to find the control with id of Author_Picture in our
       
      // template
       
      Image authorPicture = itemContainer.FindControl("Author_Picture") as Image;
       
      if (authorPicture != null)
       {
         
      // we are going to set its ImageUrl property to the value of   
         
      // Author_Picture meta field
         
      authorPicture.ImageUrl =
                contentItem.GetMetaData(
      "Author_Picture").ToString();
         
      // as a nice touch, we can set its AlternateText property (alt attribute)
         
      // to the value of the Author meta field - which will be the name of the
         
      // author
         
      authorPicture.AlternateText =
                contentItem.GetMetaData(
      "Author").ToString();
       }
      }
    6. Overwrite CreateFilter function so that we can apply our custom filter (by Author):
      CustomContentView.cs Copy Code
      protected override Telerik.Cms.Engine.IMetaSearchInfo[] CreateFilter()
      {
         
      // we are going to call the CreateFilter function on the client
         
      // to get the filter that ContentView creates by default
         
      IMetaSearchInfo[] defaultContentViewFilter = base.CreateFilter();

         
      // we are going to create a new filter and add to it the
         
      // defaultContentViewFilter
         
      List<IMetaSearchInfo> newFilter = new
            
      List<IMetaSearchInfo>(defaultContentViewFilter);
         
      // if AuthorFilter is not empty we are going to add the condition for
         
      // author
         
      if(!String.IsNullOrEmpty(this.AuthorFilter))
         {
            MetaSearchInfo authorFilter =
      new
                
      MetaSearchInfo(MetaValueTypes.ShortText, "Author",
                
      this.AuthorFilter, JoinType.And);
               
            newFilter.Add(authorFilter);
         }
         
      // we will return new filter (converted to array because that is the
         
      // expected return type of this function)
         
      return newFilter.ToArray();
      }
    7. Build the project and make sure that build succeeds.

       

     

    PART 5: Add New Control to Sitefinity and Test it

    1. Login to Sitefinity administration area
    2. Create a new page
    3. While in Page Editor, click on the Upload control button
    4. Select "or, Upload Control as a .DLL file" radio button
    5. Select the SampleControl.dll file (it should be in the bin folder in the folder where you have placed your C# class library project – the one created in PART 2)
    6. Your control should display two items along with the Author pictures. Edit control and set the name of the Author by which you want to filter the list of Content Items to test out the filtering implementation.

     

    Download the Sample Code from here.

     

    See Also

    Sitefinity Building Parts: Generic Content Based Modules
    Generic Content Public Controls
    Generic Content Overview
    News Public Controls
    Blogs Overview
    Events Public Controls

    Sitefinity Building Parts: Controls
    Controls Overview