How To Set A Default Display Option View For An Episerver 10 Block

Today's tutorial is going to discuss how you can set a default display option rendering size for your Episerver blocks.  If you are new to Episerver display options, then I suggest you read this article first, How To Configure Episerver To Allow Users To Render Blocks At Different Sizes.  When we work with Episerver and we want to allow content editors to define the widths of the blocks, we need to enable/set the display option feature, as you can see below:



When you enable the display option feature within Episerver, you give a lot more power and flexibility to the content editor, however, you also introduce a little bit more technical complexity as well.... On a normal project, you definitely don't want every single block to display by default in the same way.  Usually a carousel for example, should always be rendered on a page in a full-width display.

This requirement of not wanting all blocks to be rendered in every single way possible, highlights one of the main issues with Display Options in Episerver....  it's an all/or nothing feature.  When you enable display options, every single block will magically have a 'Display As' option next to it that will allow a content editor to specify the width of the block.  As display options are all or nothing, then as the developer/designer on the project, you'll need to figure out how this will be managed.  You will never want every single block within your solution to be configurable to every width possible.  In today's tutorial I'm going to talk about the different options available within Episerver to make this process less painful.  

If you followed my first tutorial about display options, then by default, all blocks will be rendered as full-width controls. On most projects however, the reality is that you will want the automatic display option to behave differently on a per block basis.  In today's tutorial, I'm going to cover all the code that you will need to accomplish that in Episerver... so let's begin.

How Can I Make Sure My Episerver Blocks Look Correct?

 When it comes to ensuring content editors use the right display option we have a few options:

1. Trust the content editors.  In most places I've worked, content editors aren't stupid and if they see they've added a block and it doesn't look good, they remove it, or they experiment with the display option until it looks OK.  This approach of doing nothing is the quickest and easiest for the developers, but in some companies, they don't want to trust their staff etc..  so for whichever reason they need to look things down a bit more

2. If your block only needs to render in one way, don't inject the display tag option into it... d'uh!  This is another simple priciple, to make a block display in different widths, within your blocks razor HTML view, you will need to get the tag associated against it from the route value collection and then set it in your view..  simply don't do this.  f you write your HTML to only work one way and you don't intergrate the code to switch the class, the HTML won't switch

3. This is where things get more tricky, you need two or more display options, say full width and half width.  By default you want the block to display in half width the first time it's dragged onto a content area.  This is where the code below will help.

Boiler Plate Code

To get this up and running we need a lot of boilerplate code.  I'll quickly run through everything I think you'll need on your project, I've also uploaded a Display option Sample Project into my Github account here which has a workig version of everything in this tutorial.

Enum To Store The Display Options

 public enum DisplayOptionEnum
    {
        Unknown,

        [BootstrapClass(Name = "col-md-12")]
        Full = 12,

        [BootstrapClass(Name = "col-md-9")]
        ThreeQuaters = 9,

        [BootstrapClass(Name = "col-md-6")]
        Half = 6,

        [BootstrapClass(Name = "col-md-3")]
        Quater = 3,
    }

Whenever I enable Display Options on a project, I recommend using a custom DisplayOptionEnum enum. In this way, you can have one thing that defines the display option name to use in the Episerver editor, the bootstrap class name associated against it, the columns width etc... 

Interface

    public interface IDefaultDisplayOption
    {
        DisplayOptionEnum DefaultDisplayOption { get; }
    }

To set a default display option size on a block, we need a way to identify it. I'm a big advocate of solid and design patterns, so whenever I need to do anything like this I always go for composition over inheritance. So, basically, if you add this interface to a block, it will get picked up as something with a default size. This will be useful later on.

Block Definition

    [ContentType(DisplayName = "Colour Block",
        GUID = "EB15ECE1-341D-4F3D-887B-315963732790",
        Description = "Colour text")]
    public class ColourBlock : BlockData, IDefaultDisplayOption
    {
        public DisplayOptionEnum DefaultDisplayOption => DisplayOptionEnum.ThreeQuaters;
    }

This is a simple example, of a block that implements the interface.

Custom Content Area

This is the code where the magic happens!  

  [ServiceConfiguration(typeof(AddDefaultDisplayOptionContentAreaRenderer), Lifecycle = ServiceInstanceScope.Unique)]
    public class AddDefaultDisplayOptionContentAreaRenderer : ContentAreaRenderer
    {
        protected override string GetContentAreaItemTemplateTag(HtmlHelper htmlHelper, ContentAreaItem contentAreaItem)
        {
            var templateTag = base.GetContentAreaItemTemplateTag(htmlHelper, contentAreaItem);

            if (!string.IsNullOrWhiteSpace(templateTag))
                return templateTag;

            var defaultDisplayOption = contentAreaItem.GetContent() as IDefaultDisplayOption;
            
            return defaultDisplayOption?.DefaultDisplayOption.ToString() ?? DisplayOptionEnum.Full.ToString();
        }
    }
}

In here we inherit from ContentAreaRendered and over the GetContentAreaItemTemplateTag method.  In the method we're passed in the ContentAreaItem so all we have to do is check that the display option is empty (for automatic view).  If the display option hasn't been set and the block implements the IDefaultDisplayOption interface, we return that value.  The code's pretty simple, but it does everything we need it to.

Lastly, we need the code to render our custom content area render within our view:

public static class ContentAreaExtensions
    {
        internal static Injected AddDefaultDisplayOptionContentAreaRenderer;

        public static void RenderDefaultDisplayOptionContent(this HtmlHelper htmlHelper, ContentArea contentArea)
        {
            AddDefaultDisplayOptionContentAreaRenderer.Service.Render(htmlHelper, contentArea);
        }
    }

The Razor HTML code

       
@{
        Html.RenderDefaultDisplayOptionContent(Model.CurrentPage.DefaultDisplayOptionArea;
}

Code Sample

You can find a fully working website with this code intergrated into it from my Github account in the Display Option Project

 

submit to reddit

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

Back to top