Dynamic modules built with the Module Builder give you the ability to relate items using Guid fields. But after relationships between content types are defined, it is nice to have the items displayed and in the front end. With the 5.1 release we have done some modifications to the dynamic content widgets which provide you with that ability.
To configure the dynamic content widgets first we need to have some content types and data. For instance you could have "Artist" and "Albums" types related in a way that the "Artist" type has a field “Albums” that is an array of GUIDs field and it is populated with the IDs of the related albums.
Here is sample code of what I am trying to describe. First we create our data:
public
void
CreateData()
{
List<Dictionary<Guid,
string
>> albumCollection =
new
List<Dictionary<Guid,
string
>>()
{
new
Dictionary<Guid,
string
>()
{
{Guid.NewGuid(),
"album 1 for artist 1"
},
{Guid.NewGuid(),
"album 2 for artist 1"
},
{Guid.NewGuid(),
"album 3 for artist 1"
}
},
new
Dictionary<Guid,
string
>()
{
{Guid.NewGuid(),
"album 1 for artist 2"
},
{Guid.NewGuid(),
"album 2 for artist 2"
},
{Guid.NewGuid(),
"album 3 for artist 2"
}
}
};
foreach
(var collection
in
albumCollection)
{
foreach
(KeyValuePair<Guid,
string
> kvp
in
collection)
{
CreateAndPublishAlbum(kvp.Key, kvp.Value);
}
}
CreateAndPublishArtist(
"artist 1"
,
"Rock"
, albumCollection[0].Keys.ToArray());
CreateAndPublishArtist(
"artist 2"
,
"Pop"
, albumCollection[1].Keys.ToArray());
}
public
void
CreateAndPublishAlbum(Guid itemId,
string
title)
{
DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager();
Type albumsType = TypeResolutionService.ResolveType(
"Telerik.Sitefinity.DynamicTypes.Model.RelatedDataTest.Albums"
);
DynamicContent albumsItem = dynamicModuleManager.CreateDataItem(albumsType, itemId, dynamicModuleManager.Provider.ApplicationName);
// This is how values for the properties are set
albumsItem.SetValue(
"Title"
, title);
albumsItem.SetValue(
"Owner"
, SecurityManager.GetCurrentUserId());
albumsItem.SetValue(
"PublicationDate"
, DateTime.Now);
albumsItem.SetValue(
"UrlName"
,
new
Lstring(Regex.Replace(title, UrlNameCharsToReplace, UrlNameReplaceString)));
// We can now call the following to publish the item
ILifecycleDataItem publishedAlbumsItem = dynamicModuleManager.Lifecycle.Publish(albumsItem);
//You need to set appropriate workflow status
albumsItem.SetWorkflowStatus(dynamicModuleManager.Provider.ApplicationName,
"Published"
);
// You need to call SaveChanges() in order for the items to be actually persisted to data store
dynamicModuleManager.SaveChanges();
}
//Publish a new artists item
public
void
CreateAndPublishArtist(
string
title,
string
musicStyle, Guid[] albums)
{
DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager();
Type artistsType = TypeResolutionService.ResolveType(
"Telerik.Sitefinity.DynamicTypes.Model.RelatedDataTest.Artists"
);
DynamicContent artistsItem = dynamicModuleManager.CreateDataItem(artistsType);
// This is how values for the properties are set
artistsItem.SetValue(
"Name"
, title);
artistsItem.SetValue(
"Owner"
, SecurityManager.GetCurrentUserId());
artistsItem.SetValue(
"Albums"
, albums);
artistsItem.SetValue(
"MusicStyle"
, musicStyle);
artistsItem.SetValue(
"UrlName"
,
new
Lstring(Regex.Replace(title, UrlNameCharsToReplace, UrlNameReplaceString)));
// We can now call the following to publish the item
ILifecycleDataItem publishedArtistsItem = dynamicModuleManager.Lifecycle.Publish(artistsItem);
//You need to set appropriate workflow status
artistsItem.SetWorkflowStatus(dynamicModuleManager.Provider.ApplicationName,
"Published"
);
// You need to call SaveChanges() in order for the items to be actually persisted to data store
dynamicModuleManager.SaveChanges();
}
private
const
string
UrlNameCharsToReplace = @
"[^\w\-\!\$\'\(\)\=\@\d_]+"
;
private
const
string
UrlNameReplaceString =
"-"
;
As you can see two artists and six albums are created. Albums IDs are passed to the artists “Albums” fields so that the relations are set. Every artists has three albums. The next step will be to configure the widgets that are created with the custom content types. For this purpose we have added two new properties in the widgets. Place both content types widgets in a single page and in the albums widget advanced settings set RelatedDataTypeName to the content type name of the artist type (Telerik.Sitefinity.DynamicTypes.Model.RelatedDataTest.Artists). Set RelatedDataFieldName property in the same widget to the name the field of the related type where the id’s of the items are stored – in this case “Albums” field of the artist content type. Save and publish. When the page is viewed in the front end and an artist is selected the corresponding albums will be displayed.
With the latest version of Sitefinity Thunder comes a very nice option to create items selector for your related data in the backend which will ease the process. Have a look at the documentation article about configuring the new selector control.
Here you can find a video that goes through all of the configuration steps.