There are few ways for grouping properties in edit mode. You could place properties that should be grouped in a separate tabs. Another option is to define new block type that contains related properties and use the block on page. But when you don’t want to have too many tabs or block types you could try to use my custom implementation. In this article I will show functionality of grouping properties using header.
Grouping properties
Let’s consider following scenario. We have a page that contains address properties (street, city, state) and few properties for storing phone numbers (main phone, sales department, customer support). All properties are under Company tab.
We would like to to group address properties and phone properties. To do this we could create two tabs Address and Phones, or create AddressBlock and PhonesBlock block types and use them as page properties. For example, when Contact block from Alloy is added to TestPage page:
1 2 3 4 5 6 7 8 9 10 |
namespace AlloyTemplates.Models.Pages { public class TestPage : SitePageData { [Display(GroupName = "Contact")] public virtual ContactBlock MainContact { get; set; } // other properties } } |
In edit mode, it will be rendered like:
The name of the property will be grouping title.
Grouping properties using header
My new plugin is working in a similar way to local blocks solution. It will display header above the first property from the group.
Headers are defined using GroupingHeaderAttribute wich has Title parameter. The attribute should be used on the first property from the group. For address properties it will be “AddressStreet” and for Phone properties it will be “PhoneMain”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public class TestPage : SitePageData { [GroupingHeader("Company address")] [Display(GroupName = "Company", Order = 1)] public virtual string AddressStreet { get; set; } [Display(GroupName = "Company", Order = 2)] public virtual string AddressCity { get; set; } [Display(GroupName = "Company", Order = 3)] public virtual string AddressState { get; set; } [GroupingHeader("Contact phones")] [Display(GroupName = "Company", Order = 4)] public virtual string PhoneMain { get; set; } [Display(Name="Sales department", GroupName = "Company", Order = 5)] public virtual string PhoneSalesDepartment { get; set; } [Display(GroupName = "Company", Order = 6)] public virtual string PhoneCustomerSupport { get; set; } } |
After running the site it will render properties and headers:
Styling headers
Together with the Title you can set CssClass and Tag parameters. Using those settings you can customize header layout.
In Alloy solution, the edit mode styles should be added to “ClientResources/styles/styles.css”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
.address-group, .emails-group, .press-group { background-color: #d0d0d0; } .address-group > h3:before, .emails-group > h3:before, .press-group > h3:before { content: " "; display: inline-block; width: 24px; height: 24px; float: left; margin-right: 5px; background: url(/EPiServer/Shell/11.1.0.0/ClientResources/epi/themes/sleek/epi/images/icons/commonIcons24x24.png) 0 -288px no-repeat; } .address-group > h3 { font-style: italic } .emails-group > h3 { color: red; } .emails-group > h3:before { background-position-y: -192px; } .press-group > h3 { font-family: "Courier new" } .address-group > h3:before { background-position-y: -96px; } |
Localizing header title
You can also translate the title using resource files. It’s similar to translating property caption. The resourcekey format for header is
“contentType / [type name] / properties / [property name] / groupingheader“.
For example to translate property “testg11” from “TestPage” page, the XML will look like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="utf-8"?> <languages> <language name="English" id="en"> <contenttypes> <!-- TestPage --> <testpage> <properties> <testg11> <groupingheader>Company address (EN)</groupingheader> <caption>Street (EN)</caption> </testg11> </properties> </testpage> <!-- Other properties --> </contenttypes> </language> </languages> |
The full source code is available on github (grouping-header branch). There are two nuget packages nuget and nuget for .Net core.