EPiServer creation and management of non-common content types
![](https://i0.wp.com/www.cdisol.blog/wp-content/uploads/2019/12/sen5.png?fit=975%2C515&ssl=1)
During the EPiServer Ascend event I attended a lab called external content replication which I though was quite interesting, you can find the instructions here. The lab showed us how to treat external content, integrate it in EPiServer using a job, save it outside of the root site and create these content types in a different tab of the assets pane. What I decided to do is to replicate this lab and explain it more in depth, in special how to create non common content types which do not fit as blocks or pages but should be handled by the CMS anyway.
![epi_server_logo_detail](https://i0.wp.com/www.cdisol.blog/wp-content/uploads/2018/03/epi_server_logo_detail.png?resize=696%2C464&ssl=1)
So, lets begin !!!!
First, I am going to begin creating a content type which in this case it is not going to inherit from BlockData or PageData. From the lab I learned that you can also inherit from other classes which provides several of the functionality of those two classes but can be used in different scenarios like this one. These classes are explained in the link above, but I will show them here for completion purposes:
Class Name | Description |
BasicContent | Basic implementation of IContent |
ContentBase | Inherits from BasicContent but adds IVersionable and IModifiedTrackable interfaces implementations |
StandardContentBase | Inherits from ContentBase but adds ILocalizable and even more EPiServer interfaces implementations |
You can also add more interfaces to your content types as required. The new content type is going to inherit from StandardContentBase and it will describe a person in a business. The class has the following code
using System.ComponentModel.DataAnnotations;
using EPiServer.Core;
using EPiServer.DataAnnotations;
namespace Foundation.Cms.People
{
[ContentType(DisplayName = "Person Content", GUID = "c41959cf-efc1-4e5f-b79d-78d3b8e5af13")]
public class PersonContent : StandardContentBase // Inherits from a different class PageData or BlockData
{
[Required]
[Display(Name = "First Name", Order = 10)]
public virtual string FirstName { get; set; }
[Required]
[Display(Name = "Last Name", Order = 20)]
public virtual string LastName { get; set; }
[CultureSpecific]
[Required]
[Display(Name = "Job Position", Order = 30)]
public virtual string JobPosition { get; set; }
[Required]
[Display(Name = "Age", Order = 40)]
public virtual int AddressLine2 { get; set; }
}
}
Now, I am going to choose where these new content types items are going to live because we do not want this content to be part of our main site tree structure. We will create an initialization module which will create a new folder below the root level where will be saving these new items
using System;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
namespace Foundation.Cms.People
{
[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class PeopleRootInitialization : IInitializableModule
{
public void Initialize(InitializationEngine context)
{
var contentRootService = context.Locate.Advanced.GetInstance<ContentRootService>();
// We create a folder at the root level called People
contentRootService.Register<ContentFolder>("People", new Guid("c41959cf-efc1-4e5f-b79d-78d3b8e5af14"), ContentReference.RootPage);
}
public void Uninitialize(InitializationEngine context)
{
}
}
}
We will also create a new content repository descriptor which will define several aspects of the People content folder created in the initialization module. The aspects we defined are
Aspect | Description | Value |
Key | Key for this new content repository descriptor | People |
Name | Name of the content repository descriptor | People |
Roots | What is the root where the content repository descriptor is applied | People folder from Root |
ContainedTypes | Which types can be inside | PersonContent, ContentFolder |
CreatableTypes | Which types can be created inside | PersonContent, ContentFolder |
LinkableTypes | Which types can be linked inside | PersonContent |
MainNavigationTypes | Which types can be used as part of the navigation tree structure | ContentFolder |
What we are trying to say with these properties and values is that we are going to allow only PersonContent and ContentFolder items to be inside the folder People, that we are only allowing to create items of the same two types, that you can only link PersonContent items and that we can only use ContentFolder items as part of our navigation tree. The property Roots is using a variable _root which is initialized in the constructor with the folder we created in the initialization module. The code is the following:
using System;
using System.Collections.Generic;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.ServiceLocation;
using EPiServer.Shell;
namespace Foundation.Cms.People
{
[ServiceConfiguration(typeof(IContentRepositoryDescriptor))]
public class PeopleContentRepositoryDescriptor : ContentRepositoryDescriptorBase
{
private readonly ContentReference _root;
public PeopleContentRepositoryDescriptor(ContentRootService contentRootService)
{
_root = contentRootService.Get("People");
}
public override string Key => "people";
public override string Name => "People";
public override IEnumerable<ContentReference> Roots => new[] { _root };
public override IEnumerable<Type> ContainedTypes => new[] { typeof(PersonContent), typeof(ContentFolder) };
public override IEnumerable<Type> CreatableTypes => new[] { typeof(PersonContent), typeof(ContentFolder) };
public override IEnumerable<Type> LinkableTypes => new[] { typeof(PersonContent), };
public override IEnumerable<Type> MainNavigationTypes => new[] { typeof(ContentFolder), };
}
Finally, we will create a UI component. It will use our content repository descriptor created above to define properties in the editor UI such as: sort order, name (in the UI) and in which area will be shown inside the editor. The properties we defined for this UI component are:
Property | Description | Value |
Title | Title of the UI component | People |
Categories | Category of the UI component | content |
PlugInAreas | Where in the UI is going to be located | PlugInArea.AssetsDefaultGroup, PlugInArea.NavigationDefaultGroup |
SortOrder | In which position is going to appear | 1000 |
Settings | Settings configuration for the UI Component. | new Setting(“repositoryKey”, “people”) |
We added the repository key setting to the UI component and set it to the content repository descriptor defined in the previous class using its key “people”
using EPiServer.Shell;
using EPiServer.Shell.ViewComposition;
namespace Foundation.Cms.People
{
[Component]
public class PeopleTreeComponent : ComponentDefinitionBase
{
public PeopleTreeComponent() : base("epi-cms/asset/HierarchicalList")
{
base.Title = "People";
Categories = new [] { "content" };
PlugInAreas = new [] { PlugInArea.AssetsDefaultGroup, PlugInArea.NavigationDefaultGroup };
SortOrder = 1000;
base.Settings.Add(new Setting("repositoryKey", "people"));
base.Settings.Add(new Setting("noDataMessages", new { single = "This folder does not contain any locations", multiple = "These folders do not contain any locations" }));
}
}
}
There is an additional setting called “noDataMessages”, this setting is required to make this example work. You can find more details about why is needed in the lab link
We will now compile the code and run it. Go to the CMS editor and see if the People tab appears in any of the plugin areas, we defined in the UI component
![](https://i0.wp.com/www.cdisol.blog/wp-content/uploads/2019/12/sen1.png?resize=696%2C345&ssl=1)
If the tab or tabs does not appear. You can press the profile icon at the top right corner, press my settings, click in display options and hit the reset view (As stated in the lab link)
![](https://i0.wp.com/www.cdisol.blog/wp-content/uploads/2019/12/sen2.png?resize=594%2C446&ssl=1)
You can now create some persons or folders inside the people tab -people folder and use those items anywhere in the CMS
![](https://i0.wp.com/www.cdisol.blog/wp-content/uploads/2019/12/sen3.png?resize=696%2C377&ssl=1)
![](https://i0.wp.com/www.cdisol.blog/wp-content/uploads/2019/12/sen4.png?resize=379%2C313&ssl=1)
You can check that these new files are being saved outside of the main site tree structure by going to the admin interface, admin tab, set access rights option
![](https://i0.wp.com/www.cdisol.blog/wp-content/uploads/2019/12/sen5.png?resize=696%2C368&ssl=1)
5 COMMENTS