This content is archived. See latest version here

Last updated: Jul 09 2014

Table of contents

Introduction

This document describes different ways you can control how content is presented and behaves in the EPiServer user interface. Content is a central feature in EPiServer products. In EPiServer 7.0 the content system was introduced with usage of the central types pages and blocks in EPiServer CMS. With the EPiServer 7.5 release, the Commerce catalog is now also delivered as content as well as the new Media system used by both CMS and Commerce. In order to make different content types appear and behave differently there is something called UI Descriptors that can be used to describe the behaviour of a content type, for instance setting the icon used to display items of the type.

UI descriptors

There has been many improvements in the system to actually make use of these. A UI descriptor is a class that can be used to describe appearance and behavior for a type, as shown in the following simple example:


[UIDescriptorRegistration]
    public class ContainerPageUIDescriptor : UIDescriptor<ContainerPage>
    {
        public ContainerPageUIDescriptor()
            : base("epi-iconObjectPage")
        {
        }
    }
        

What the code above does is to describe how objects of the custom type ContainerPage behaves in the user interface. In this sample we specify the CSS classes used to display the item, for instance in listings or trees.

Inheritance

The type descriptor supports inheritance. This means that when behavior is not defined on the specific type, it will check if there are any descriptors for any parent types that describe the behavior that is requested. For instance, if a page type does not specify a custom icon then the generic icon for pages will be used.

Resources

It is also possible to add type specific translations for the user interface. This might be used when creating, moving or deleting items etc. The following example shows how an XML resource file with type translations can look like:

XML
<language name="English" id="en">
    <contenttypes>
        <icontentdata>
            <name>Content</name>
            <create>New Item</create>
            <move>Move Item</move>
        </icontentdata>
        <blockdata>
            <name>Block</name>
            <create>New Item</create>
            <move>Move Item</move>
        </blockdata>
        <youtubeblock>
            <name>You Tube Block</name>
            <create>New You Tube Block</create>
            <move>Move You Tube Block</move>
        </youtubeblock>
    </contenttypes>
</language>

In the example above we set some generic “fallback” texts for any content, some more specific texts for blocks and really specific texts for “YouTube blocks” (assuming that this is a type in your solution). Default behaviour is to default to a language node under “contenttypes” with the name of the type without namespace. It is possible to change the key used by defining the LanguageKey property of your type descriptor, for instance if you have classes in different namespaces with the same class name.

Content repository descriptors

In order to be able to be able to standardize components that show content from different repositories a new entity called content repository descriptors has been added. The purpose of this class is to describe a repository so that the UI can auto-generate with the settings for a repository. This can be used to create navigation components, such as the page tree or selection widgets such as the page selector. The following example shows how the implementation for the block repository descriptor:

C#
using System;
using System.Collections.Generic;
using EPiServer.Core;
using EPiServer.Framework.Localization;
using EPiServer.ServiceLocation;
using EPiServer.Web;

namespace Samples
{
    [ServiceConfiguration(typeof(IContentRepositoryDescriptor))]
    public class BlockRepositoryDescriptor : ContentRepositoryDescriptorBase
    {
        public static string RepositoryKey { get { return "blocks"; } }

        public override string Key { get { return RepositoryKey; } }

        public override string Name
        {
            get { return LocalizationService.Current.GetString("/contentrepositories/blocks/name"); }
        }

        public override IEnumerable<ContentReference> Roots
        {
            get
            {
                var roots = new List<ContentReference> { SiteDefinition.Current.GlobalAssetsRoot };

                if (SiteDefinition.Current.GlobalAssetsRoot != SiteDefinition.Current.SiteAssetsRoot)
                {
                    roots.Add(SiteDefinition.Current.SiteAssetsRoot);
                }

                return roots;
            }
        }

        public override string SearchArea { get { return "CMS/blocks"; } }

        public override Type[] ContainedTypes
        {
            get { return new Type[] { typeof(ContentFolder), typeof(BlockData) }; }
        }

        public override Type[] MainNavigationTypes
        {
            get { return new Type[] { typeof(ContentFolder) }; }
        }

        public override bool SupportsWastebasket { get { return true; } }

        public override int SortOrder { get { return 200; } }

        public override string[] MainViews { get { return new[] { HomeView.ViewName }; } }
    }
}

The sample below shows how the content repository can be used to create a content selector for blocks within the repository:


using EPiServer.Core;
using EPiServer.Shell.ObjectEditing.EditorDescriptors;
using EPiServer.Web;

namespace Samples
{
    [EditorDescriptorRegistration(TargetType = typeof(ContentReference), UIHint = UIHint.Block)]
    public class BlockReferenceEditorDescriptor : ContentReferenceEditorDescriptor<BlockData>
    {
        public override string RepositoryKey
        {
            get
            {
                return BlockRepositoryDescriptor.RepositoryKey;
            }
        }
    }
}
        

And below is another example of usage that shows how to set up a component in the assets pane of the CMS main view that shows content from the repository:


using EPiServer.Shell.ViewComposition;

namespace Samples
{
    [Component]
    public class SharedBlocksComponent : ComponentDefinitionBase
    {
        public SharedBlocksComponent()
            : base("epi-cms.component.SharedBlocks")
        {
            LanguagePath = "/episerver/cms/components/sharedblocks";
            SortOrder = 100;
            PlugInAreas = new[] { PlugInArea.DefaultAssetsGroup };
            Categories = new[] { "cms" };

            Settings.Add(new Setting("repositoryKey", BlockRepositoryDescriptor.RepositoryKey));
        }
    }
}
        

Do you have feedback on this documentation? Send an email to documentation@episerver.com. For development-related questions and discussions, refer to our Forums on https://world.episerver.com/forum/