Render content area items without extra divs in EPiServer – The easy way

Render content area items without extra divs in EPiServer – The easy way

EPiServer content areas have the ability to show several blocks to the editor in a neat and eye catching manner if the view is using the Html.PropertyFor function, but unfortunately when the view is shown to the user, the content are wraps the blocks with extra divs which can break css styles easily. One way to fix it is adding properties such as has container in the property for function but in some scenarios it seems like this is not enough.

epi_server_logo_detail


@Html.PropertyFor(x => x.CurrentPage.MainContentArea, new
{
hascontainer = false
})

Today, what I have done is create a helper method which can be invoked on any view, goes through all the items of the content area and render them partially using a defined view. Note: This helper works only for content areas which support only one type of block at a time.


[CultureSpecific]
[AllowedTypes(typeof(LimitedBlock))]
[Display(Name = "Main Content Areat", GroupName = SystemTabNames.Content, Order = 1)]
public virtual ContentArea MainContentArea{ get; set; }

The steps to solve this problem are the following:

  1. Create the helper method in the App_Code folder
  2. Invoke the helper method from a view

So once again without more hustle lets code !!!

Create the helper method in the App_Code folder

First, we will create a helper method in a razor view called Helpers.cshtml. This file must be inside the App_Code folder in order to be available in the views of the project.


@using EPiServer.Web.Mvc
@using EPiServer.Web.Mvc.Html
@using Util.Helpers
@using System.Web.Mvc
@using System.Web.Mvc.Html
@using EPiServer.Core

@{
Layout = null;
}

@helper GenerateContentAreaItemsWithoutDivs(System.Web.Mvc.HtmlHelper html, ContentArea contentArea, string view)
{
if (contentArea != null)
{
foreach (var contentAreaItem in contentArea.Items)
{
var item = ViewHelper.GetBlock(contentAreaItem);
if (item == null)
{
continue;
}

@html.Partial(view, item)
}
}
}

The method will check if the content area is not null and iterate over the items finding which block is and render the block using the specified view.

The ViewHelper class has the static method GetBlock which calls the content repository service in order to get the Block from a content reference or content area item (By method overload).


using EPiServer.Core;
using System;
using EPiServer;
using EPiServer.ServiceLocation;

namespace Util.Helpers
{
public static class ViewHelper
{
public static readonly Injected ContentRepository;

public static T GetBlock(ContentReference reference) where T : BlockData
{
if (reference == null) return null;
return ContentRepository.Service.TryGet(reference, out T block) ? block : null;
}

public static T GetBlock(ContentAreaItem item) where T : BlockData
{
if (item == null) return null;
try
{
var result = item.ContentLink == null
? ContentRepository.Service.Get(item.ContentGuid)
: ContentRepository.Service.Get(item.ContentLink);
return result;
}
catch (Exception)
{
return null;
}
}
}
}

Invoke the helper method from a view

Finally, we will invoke the helper method GenerateContentAreaItemsWithoutDivs in a razor view


@using EPiServer.Web.Mvc.Html

@model Models.Pages.PostsPage

@if (Model != null)
{
@Helpers.GenerateContentAreaItemsWithoutDivs(Html, Model.PostsContentArea, "~/Views/Blocks/PostBlock.cshtml")
}

The page model class Posts page has only one property Posts content area which allows only Post blocks.


using System;
using System.ComponentModel.DataAnnotations;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.DataAnnotations;
using Models.Blocks;

namespace Models.Pages
{
[ContentType(DisplayName = "Posts Page", GUID = "d89f5f77-77f2-4e9f-b61a-71357bb8ff10", Description = "This is a Posts Page")]
public class PostsPage : PageData
{
[CultureSpecific]
[AllowedTypes(typeof(PostBlock))]
[Display(Name = "Posts Content Area", Description = "Posts Content Area", GroupName = SystemTabNames.Content, Order = 1)]
public virtual ContentArea PostsContentArea { get; set; }
}
}

The block model class Post block has two fields one for the title (string) and another one for the content (XhtmlString)


using System;
using System.ComponentModel.DataAnnotations;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.DataAnnotations;

namespace Models.Blocks
{
[ContentType(GUID = "838fe4e6-9f13-419b-bed1-16409f08e4fa")]
public class PostBlock : BlockData
{
[Display(GroupName = SystemTabNames.Content, Order = 100)]
[CultureSpecific]
public virtual string Title { get; set; }

[Display(GroupName = SystemTabNames.Content, Order = 200)]
[CultureSpecific]
public virtual XhtmlString Content { get; set; }
}
}

The view for the block model PostBlock has only two html property for functions for each property inside the block


@using EPiServer.Web.Mvc.Html

@model Models.Blocks.PostBlock

@if (Model == null) { return; }

@Html.PropertyFor(x => x.Title)
@Html.PropertyFor(x => x.Content)

And that is all. Every time the user goes to the CMS editor and create a post page with one or more post blocks it will render the blocks without extra divs.

I hope it will help someone and as always keep learning !!!

Written by:

Jorge Cardenas

Developer with several years of experience who is passionate about technology and how to solve problems through it.

View All Posts

Leave a Reply