EPiServer Content Area Renderer With Row Support

EPiServer Display options is a really nice feature but it's lacking a row rendering option for Bootstrap Grid system.


Without row-elements your grid will got broken quite easily and you need to create "dirty CSS hacks" to fix it.


To create rich content with various types of blocks and content sizes you need to separate the rows with <div class="row"> -element.


Luckily EPiServer is so extendable that you can add the feature quite easily in your own project. So after adding the following codes you are able to get these rows and your HMTL is properly formatted for Bootstrap grid or some other grid system.



Adding rows in content area renderer is actually pretty simple job. You can make it much more fail safe and improved but this is the simple version.

    public class ContentAreaRendererWithRows : ContentAreaRenderer
	    // Wraps every 12 cells with row divs if the tags are used.
        protected override void RenderContentAreaItems(HtmlHelper htmlHelper, IEnumerable contentAreaItems)
            var items = contentAreaItems.ToArray();
            int rowWidthState = 0;
            var itemInfos = items.Select(item =>
                var tag = GetContentAreaItemTemplateTag(htmlHelper, item);
                var columnWidth = GetColumnWidth(tag);
                rowWidthState += columnWidth;
                return new
                    ContentAreaItem = item,
                    Tag = tag,
                    ColumnWidth = columnWidth,
                    RowWidthState = rowWidthState,
                    RowNumber = rowWidthState % 12 == 0 ? rowWidthState/12 - 1 : rowWidthState / 12,
            //if tags exists wrap items with row or not then use the deafault rendering.
            bool tagExists = itemInfos.Any(ii => !string.IsNullOrEmpty(ii.Tag));
                base.RenderContentAreaItems(htmlHelper, items);

            var rows = itemInfos.GroupBy(a => a.RowNumber, a => a.ContentAreaItem);
            foreach (var row in rows)
"); base.RenderContentAreaItems(htmlHelper, row); htmlHelper.ViewContext.Writer.Write("
"); } } public static int GetColumnWidth(string tag) { switch (tag) { case Settings.ContentAreaTags.FullWidth: return 12; case Settings.ContentAreaTags.TwoThirdsWidth: return 8; case Settings.ContentAreaTags.HalfWidth: return 6; case Settings.ContentAreaTags.OneThirdWidth: return 4; default: return 12; } } protected override string GetContentAreaItemCssClass(HtmlHelper htmlHelper, ContentAreaItem contentAreaItem) { var tag = GetContentAreaItemTemplateTag(htmlHelper, contentAreaItem); return string.Format("block {0} {1}", GetTypeSpecificCssClasses(contentAreaItem, ContentRepository), tag); } private static string GetTypeSpecificCssClasses(ContentAreaItem contentAreaItem, IContentRepository contentRepository) { var content = contentAreaItem.GetContent(contentRepository); var cssClass = content == null ? String.Empty : content.GetOriginalType().Name.ToLowerInvariant(); return cssClass; } }

    public class StructureMapConfig
        public static void ConfigureContainer(IContainer container)
            container.Configure(x =>


    public static class Settings
        public static class ContentAreaTags
            public const string FullWidth = "col-sm-12";
            public const string TwoThirdsWidth = "col-sm-8";
            public const string HalfWidth = "col-sm-6";
            public const string OneThirdWidth = "col-sm-4";


And Bob's your uncle!!!

EPiServer Display options is a really nice feature but it's lacking a row rendering option for Boots…