Try Now
More in this section
Blogs RSS feed

Working with Related Dynamic Content Items in Sitefinity

by Veselin Vasilev

This blog post can serve as a successor of the one Rado wrote a year ago on the same subject. However, there have been many improvements in the Module Builder and Sitefinity Thunder since then that will allow us to accomplish the task much easier. I hope it can be seen as a complete guide of how to work with related dynamic content items.

For the purpose of this blog, I have created a new content type called Apps. As starter, it includes just a few fields: Title, Description and ImageGallery

Figure: initial definition of the App module.

The module is active and working just fine. Now let’s add some additional functionality to it – ability to select related items (related Apps). The goal is to easily create relationships between the items (apps) so that any app can have zero, one or more related apps. That’s a common requirement, right? So let’s get started.

1. Create the dynamic content item selector with Sitefinity Thunder

First, we need to create the interface that will allow us to *select* the related apps. Thankfully, Sitefinity Thunder can generate all the code for us. Just go to your solution in Visual Studio, right click the SitefinityWebApp project and select Add > New Item. In the left pane, under your favourite language (C# or VB) select the Sitefinity category. Choose “Sitefinity Dynamic Items Field Control Selector” from the right.

Figure: adding a new dynamic items field control selector to your project.

Let’s call this file RelatedAppsControlSelector. Click add. If you’ve already installed Thunder to this project it will find all the existing dynamic modules and you can select the one you need. We select the App content type in this case:

Figure: Sitefinity Thunder successfully identified all the active dynamic module types in my project.

Sitefinity Thunder will then create a whole bunch of files for us:

Figure: Sitefinity Thunder generates all the files needed for the selector to work properly


Those files will take care of the interface for selecting related items and persisting the data in the database. Rebuild the project in Visual Studio so that the logic in those files is included in the output assembly.

2. Modify the content type to include the Related apps field

We need a field in our App module that will store information about the related apps. The one to do the job is of type Array of GUIDs (as we want to support multiple related items). Next we need to select what interface we are going to use to select the related apps. Here we enter the type of the class we added in step 1. 

Figure: Adding the RelatedApps field to the dynamic content type.

Note the value of the “Type or Virtual pat of the custom widget” field – it should contain the full path to the class that was created in step 1. Since I placed it into the ~/custom/fields/ folder I have SitefinityWebApp.Custom.Fields.RelatedAppsControlSelector in the type name.

Continue then Save and finally check the Update Widget Template option:

6. UpdateWidgetTemplate

Figure: update the widget template of the Apps so that it reflects the changes in the module structure

Now let’s go back to Content > Apps and add some items. You’ll see the Add Items button which opens up a modal window with a list of the existing apps. Very consistent with the rest of the UI in the backend. And all this without writing a single line of code!!


Figure: adding related items in dynamic content types is easy as cake

Now, let’s look how those apps look in the frontend:

8. FrontEndRelatedApps

Figure: The out-of-the-box widget template is unable to show the related apps

Not the result we are expecting, right? The reason is because the RelatedApp field stores GUID numbers of the related apps so we need a way to find the real apps behind the GUIDs and show the relevant information. To do so, we are going to override the default Full Details widget template and provide our own implementation of it.


3. Overriding the Full App Content widget template.

Create a new Web User Control in Visual Studio – I called it FullAppDetails.ascx and placed it under the ~/custom/templates folder.

Paste the following code inside of it:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="FullAppDetails.ascx.cs" Inherits="SitefinityWebApp.Custom.Templates.FullAppDetails" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.DynamicModules.Web.UI.Frontend" TagPrefix="sf" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields" TagPrefix="sf" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sf" %>
<sf:DynamicDetailContainer id="detailContainer" runat="server">
        <div class="sfitemDetails">
            <sf:SitefinityLabel ID="mainShortTextFieldLiteral" runat="server" Text='<%# Eval("Title") %>' WrapperTagName="h1" HideIfNoText="true" CssClass="sfitemTitle" />
            <sf:FieldListView ID="PublicationDate" runat="server" Format="{PublicationDate.ToLocal():MMM d, yyyy, HH:mm tt}" WrapperTagName="div" WrapperTagCssClass="sfitemPublicationDate" />
            <sf:SitefinityLabel ID="SitefinityLabel1" runat="server" Text='<%# Eval("Description")%>' WrapperTagName="div" HideIfNoText="true" CssClass="sfitemLongText" />
            <sf:ImageAssetsField ID="ImageAssetsField1" runat="server" DataFieldName="AppImageGallery" IsThumbnail="False" />
            <sf:AssetsField ID="AssetsField1" runat="server" DataFieldName="AppVideoGallery" />
            <telerik:RadListView ID="relatedAppsListView" runat="server"
                    <%--<div>No Related Apps</div>--%>
                    RELATED APPS:
                    <ul class="sflistList">
                        <asp:PlaceHolder ID="ItemsContainer" runat="server" />
                            <a href='<%# Eval("UrlName") %>'  ><%# Eval("Title") %></a>
<asp:PlaceHolder ID="socialOptionsContainer" runat="server"></asp:PlaceHolder>

Note the RadListView control we’ve added – it will show the related apps in more appropriate way. We just need to bind the list view with data – this is done in the NeedDataSource event:

protected void relatedAppsListView_NeedDataSource(object sender, Telerik.Web.UI.RadListViewNeedDataSourceEventArgs e)
    RadListView relatedAppsListView = sender as RadListView;
    DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager();
    Type appType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.Apps.App");
    DynamicContent app = ((DetailItem)relatedAppsListView.Parent).DataItem as DynamicContent;
    //the array of GUIDs of the related apps
    Guid[] relatedAppsIDs = app.GetValue("RelatedApps") as Guid[];
    //a list that will hold the related apps
    List<DynamicContent> relatedAppsCollection = new List<DynamicContent>();
    for (int i = 0; i < relatedAppsIDs.Length; i++)
        //get the related app
        DynamicContent relatedApp = dynamicModuleManager.GetDataItem(appType, relatedAppsIDs[i]);
        //add it to the list
    relatedAppsListView.DataSource = relatedAppsCollection;

Build the project and go to the backend. We should tell the widget to use this particular template in the front end. To do so, edit the page where the widget is placed and edit the widget itself. Go to Advanced > ControlDefinition > Views > DynamicContentDetailView and find the TemplatePath field. Enter the relative full path to the user control created above, e.g. ~/Custom/Templates/FullAppDetails.ascx and Save.

Now go to the details of any of the apps and you’ll see something like this:

9. RelatedAppsFrontEnd
Figure: the details page now shows the related apps


Leave a comment
  1. Vesselin May 30, 2013
    It is coming to Sitefinity soon ... 
  2. Steve Jun 05, 2013
    I'm assuming not soon enough to necessitate a blog post to tide people over :)
  3. Marz Jun 14, 2013
    I follow the steps, everything works until step 2. when I add a new 'RelatedApps' field to my module.  Then I get this error "There has been an error updating module fields!"

    I am using Sitefinity 6.0.  
  4. Marz Jun 14, 2013
    At the final step, this step "Note the RadListView control we’ve added – it will show the related apps in more appropriate way. We just need to bind the list view with data – this is done in the NeedDataSource event:" .. Where did you add the code? to what file?
  5. Vesselin Jun 17, 2013
    @Marz - the C# code goes to the code behind file (.cs) that was created automatically when the User Control was created in step 3.

    As for the error - did you rebuild the project after step 1? Did you enter the correct path to the custom widget?
  6. Dragon Sep 11, 2013
    Please, Please, Please Fix this soon! This is way too much work for something that should have been built in in the first place!!!!!!!!!!
  7. Nidhi Oct 28, 2013
    Hi Vasselin,

    I have built a custom module called Floor Plans. This has a child content type module called Locations.
    I have a separate module called Exhibitors. I was able to successfully add a related field for the Locations module to the Exhibitors module. When I click on the "Add Items.." button on the Exhibitors create new view, it opens a dialog box with a list of all Locations (a checkbox, title and date).
    For better UI, is it possible to modify the template of the dialog box so that it also shows the title of the Parent item (i.e. Floor Plan)?? EG: [checkbox] Floor Plan 1 > Location 1   [date]

  8. Feroz Mar 17, 2016


    Leave a comment