How To Sort The Tab Order In Your Episerver Pages Or Blocks

Making the CMS as user friendly as possible is one of the main keys of delivering a successful project that the business and the content editors love. One big annoyance for content editors is not having your pages and block properties tabs sorted in a user friendly manner. Most content editor want tabs to be sorted in terms of most frequently used, or, alphabetically. In today’s guide, we’re going to talk about how we can implement this type of functionality in your web project.

The easy way to add a new tab

Just in case you are very new to Episerver and don’t know about tabs, I’ll cover the basics first. When you define your [Display] properties on a pages or block properties, you can use the GroupName property to define what tab that property will display under in the CMS. To make the property display in a tab called “Example Tab” you would simply add the name you want to call the group in the GroupName property, like so:

[Display(
Name = "Page Title",
Description = "Page Title",
GroupName = "Example Tab",
Order = 100)]
public virtual string PageTitle { get; set; }

The problem with this approach is that you can’t set the order in which the tabs are rendered. As a rule of thumb, it’s on a first come, first served basis.

How To Order A Tab

If we want to be able to order our tabs however we see fit, we will first need to use a different approach when adding it into Episerver. This needs to be done using Episervers TabDefinition and TabDefinitionRepository.

In this example, I’m going to use an abstract class to define my properties, so we can do some clever stuff with structure map. If you don’t want to do this, you don’t have to, but I’m not going to cover that approach. In this guide, we will be using structure map to inject all the tabs into our tab creator. This will mean whenever you need to add a new tab into the system, all you need to do is create a new class that implements the base class and it will automatically be added into Episerver with no extra coding required. The code for the base class will look like this:

public abstract class EpiserverTabBase
{
public abstract TabDefinition CreateTab();
}

The next part of the puzzle is creating the tab definition that we create the tab in Episerver.

using EPiServer.DataAbstraction;
using EPiServer.Security;
using JonDJones.com.Core.Tabs.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JonDJones.com.Core.Tabs
{
public class MenuTab : EpiserverTabBase
{
public static string Name = "Menu Tab";
public override TabDefinition CreateTab()
{
return new TabDefinition
{
Name = Name,
RequiredAccess = AccessLevel.Read,
SortIndex = 800
};
}
}
}

In here we create a Episerver tab definition and add the properties we care about. NOTICE the SortIndex property as this is the thing that will order the tabs in Episerver. Next up, we will define structure map. We will need to tell

using System.Web.Mvc;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using StructureMap;
using JonDJones.com.Core.Tabs.Base;
namespace JonDJones.Com.Initialization
{
[InitializableModule]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class StructureMapSetUp : IConfigurableModule
{
private IContainer _container;
public void ConfigureContainer(ServiceConfigurationContext context)
{
context.Container.Configure(ConfigureContainer);
DependencyResolver.SetResolver(new StructureMapDependencyResolver(context.Container));
_container = context.Container;
}
public void Initialize(InitializationEngine context)
{
}
public void Preload(string[] parameters)
{
}
public void Uninitialize(InitializationEngine context)
{
}
private static void ConfigureContainer(ConfigurationExpression container)
{
container.Scan(a =>
{
a.AssemblyContainingType<EpiserverTabBase>();
a.AddAllTypesOf<EpiserverTabBase>();
a.RegisterConcreteTypesAgainstTheFirstInterface();
a.WithDefaultConventions();
a.SingleImplementationsOfInterface();
});
}
}
}

The secret ingredient of this configuration is the ‘AddAllTypesOf’ statement. AddAllTypesOf tells StructureMap to include all concrete classes that implements our abstract base class.

To finish up, we now have to create an Initialization Module that will add our custom tabs into Episerver when the site first loads.

[InitializableModule]
[ModuleDependency(typeof(StructureMapSetUp))]
public class TabsSortIndex : IInitializableModule
{
internal Injected<ITabDefinitionRepository> _tabDefinitionRepository;
internal IEnumerable<EpiserverTabBase> _tabs;
public void Initialize(InitializationEngine context)
{
RegisterTabs();
}
public void Uninitialize(InitializationEngine context)
{
}
private void RegisterTabs()
{
_tabs = ServiceLocator.Current.GetAllInstances<EpiserverTabBase>();
foreach(var tab in _tabs)
{
AddTabToList(tab.CreateTab());
}
}
private void AddTabToList(TabDefinition definition)
{
var existingTab = GetExistingTabDefinition(definition);
if (existingTab != null)
definition.ID = existingTab.ID;
_tabDefinitionRepository.Service.Save(definition);
}
private TabDefinition GetExistingTabDefinition(TabDefinition definition)
{
var tabs = _tabDefinitionRepository.Service.List();
return tabs.FirstOrDefault(x =>
x.Name.Equals(definition.Name, StringComparison.InvariantCultureIgnoreCase));
}
}

We have quite a lot of code here but most of it is pretty basic. In RegisterTabs we use the ServiceLocator with the GetAllInstances method. This line is the thing that will return back all the tabs in the project.

_tabs = ServiceLocator.Current.GetAllInstances<EpiserverTabBase>();

In GetExistingTabDefinition we look in the TabDefinitionRepository.List() collection to iterate through all the existing tabs registered in the website to see if the tab we are trying to insert already exists, or not.

var tabs = _tabDefinitionRepository.Service.List();
return tabs.FirstOrDefault(x =>
x.Name.Equals(definition.Name, StringComparison.InvariantCultureIgnoreCase));

If you look in the collection, you will also see the system tabs like Content and Settings. This means if we want to, we can re-order the built in tabs as well 🙂 AddTabToList simply saves the tab and assigns the existing tab id to our definition if it has been registered previously.

How To Reorder the build in Episerver Tabs

If you want to re-order the system tabs you need to create a tab definition that inherits from EpiserverTabBase. In Episerver 7 onwards there is a slight discrepancy in the naming conventions. The legacy names are still used in the tabs although the display name is different. For example

The tab called “Content” is called “Information”
The tab called “Advanced” is called “Settings”
The tab called “Metadata” is called “SEO”

If you want to change the sort order of the Content tab using the code from this article, you would need to use “Information” for the name, like so:

public class ContentTab : EpiserverTabBase
{
public override TabDefinition GetTab()
{
return new TabDefinition
{
Name = "Information",
RequiredAccess = AccessLevel.FullAccess,
SortIndex = 9999
};
}
}

To help you out, these are the default preset sort order indexs for the built in types:

Content = 10
Scheduling = 20
Settings = 30
Shortcut = 40
Categories = 50

If you followed everything correctly, then you create a page like so:

public class TestPage : PageData
{
[Display(
Name = "Page Title",
Description = "Page Title",
GroupName = "Example Tab",
Order = 50)]
public virtual string PropertyOne { get; set; }
[Display(
Name = "Page Title",
Description = "Page Title",
GroupName = "Secialised",
Order = 100)]
public virtual string PropertyTwo { get; set; }
}

Your editor will look like this:

episerver_menu_tab_sort_order

Conclusion

In today’s guide, we’ve talked about how to simplify content editors lives by making your pages and blocks more user friendly. We’ve discussed the basic way to create a tab by just adding text to the GroupName property. This howevever does not allow us any wiggle room to order them in a pleasing way.

In order to be able to sort tabs, we must add them into Episerver as TabDefinitions adding the sort order we care about. After we have created our TabDefinition, we need to use the Tab Definition Repositories save method to add it into Episerver. When working with the TabDefinitionRepository, we also get access to the preset/default Episerver tabs. By overriding these types we can change the sort order for these default values.

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

More Posts

6 replies
      • Scott Reed
        Scott Reed says:

        Yeah all good, send you a message on FB. Yeah the new stuff if pretty good, I can definitely see it being handy limiting certain areas but access.

        Reply
  1. Lockevn
    Lockevn says:

    FYI about “slight discrepancy in the naming conventions”, EPiServer system tabs have their names defined in
    EPiServer.DataAbstraction.SystemTabNames.Content
    EPiServer.DataAbstraction.SystemTabNames.Settings

    and so on.

    Reply

Trackbacks & Pingbacks

  1. […] you can do to improve content editors lives easier. I’ve talked previously about things like, How To Sort The Tab Order In Your EpiServer Pages Or Blocks, How To Return Different Valdation Warnings To Content Editors When Publishing In EpiServer and […]

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *