Episerver 7 : Extra divs in content area how to remove them ?

In Episerver 7 onwards, you may notice that the CMS injects two tags above and below all content areas.  When it comes to keeping a static design in-sync with your CMS site, very often you will get broken styles and a lot of crazyness. The extras are required by Episerver in order to provide the on page editing features. This is all fine but these are also rendered in the live view, adding in extra tags that are not needed

Episerver stance on the matter is that people won’t want to maintain separate CSS for live and preview.  If you only have a small site, the easy way is to use the built in features and override or change the child tags Episerver creates, like so:

@Html.PropertyFor(x => Model.ContentArea, new
{
CustomTag = "ul",
CssClass = "list",
ChildrenCustomTagName = "li",
ChildrenCssClass = "list_item",
Tag = string.Empty
})
[/cshap]
If you work in a company that has a very strict about mark-up, standards or you spend more time working between a static version and your CMS version then you might want to come up with a solution to completely remove it in live mode.  The below bit of code does this:
[ServiceConfiguration(typeof(CustomContentAreaRenderer), Lifecycle = ServiceInstanceScope.Unique)]
public class CustomContentAreaRenderer : ContentAreaRenderer
{
private readonly ContentFragmentAttributeAssembler _attributeAssembler;
private readonly IContentRenderer _contentRenderer;
private readonly IContentRepository _contentRepository;
private readonly TemplateResolver _templateResolver;
public CustomContentAreaRenderer(IContentRenderer contentRenderer, TemplateResolver templateResolver, ContentFragmentAttributeAssembler attributeAssembler)
: base(contentRenderer, templateResolver, attributeAssembler)
{
_contentRenderer = contentRenderer;
_templateResolver = templateResolver;
_attributeAssembler = attributeAssembler;
}
public CustomContentAreaRenderer(IContentRenderer contentRenderer, TemplateResolver templateResolver, ContentFragmentAttributeAssembler attributeAssembler, IContentRepository contentRepository)
: base(contentRenderer, templateResolver, attributeAssembler, contentRepository)
{
_contentRenderer = contentRenderer;
_templateResolver = templateResolver;
_attributeAssembler = attributeAssembler;
_contentRepository = contentRepository;
}
protected override void RenderContentAreaItem(HtmlHelper htmlHelper, ContentAreaItem contentAreaItem, string templateTag, string htmlTag, string cssClass)
{
var dictionary = new Dictionary<string, object>();
dictionary["childrencustomtagname"] = htmlTag;
dictionary["childrencssclass"] = cssClass;
dictionary["tag"] = templateTag;
dictionary = contentAreaItem.RenderSettings.Concat(
(
from r in dictionary
where !contentAreaItem.RenderSettings.ContainsKey(r.Key)
select r
)
).ToDictionary(r => r.Key, r => r.Value);
htmlHelper.ViewBag.RenderSettings = dictionary;
var content = contentAreaItem.GetContent(_contentRepository);
if (content != null)
{
using (new ContentAreaContext(htmlHelper.ViewContext.RequestContext, content.ContentLink))
{
var templateModel = ResolveTemplate(htmlHelper, content, templateTag);
if ((templateModel != null) || IsInEditMode(htmlHelper))
{
if (IsInEditMode(htmlHelper))
{
var tagBuilder = new TagBuilder(htmlTag);
AddNonEmptyCssClass(tagBuilder, cssClass);
tagBuilder.MergeAttributes<string, string>(
_attributeAssembler.GetAttributes(
contentAreaItem, IsInEditMode(htmlHelper), (bool)(templateModel != null)));
BeforeRenderContentAreaItemStartTag(tagBuilder, contentAreaItem);
htmlHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag));
htmlHelper.RenderContentData(content, true, templateModel, _contentRenderer);
htmlHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.EndTag));
}
else
{
htmlHelper.RenderContentData(content, true, templateModel, _contentRenderer);
}
}
}
}
}
private void RenderEditorView()
{
}
protected override bool ShouldRenderWrappingElement(HtmlHelper htmlHelper)
{
return false;
}
}

Things to note about the above code, it uses ServiceConfiguration attribute.  This attribute will register the class so you can use ServiceLocator.Current.GetInstance(); to get it.  The code basically goes through and if the page is in edit mode, adds in the epi specific div’s. If the page is in normal view mode the tags are not rendered.

In order to call the customer content area, you need to override the default content area html. In your View -> Shared folder.  You need to create a DisplayTemplates folder and create a file called ContentArea.cshtml.  This will override the default view. If you want to, you can also override things like, Paragraph.cshtml, H2.cshtml, Image.cshtml etc..

In your view, we are going to create an HTML helper that will call the custom content area code

@{
Html.RenderCustomContentArea(Model);
}

the extension method will then look like this

public static class ContentAreaExtensions
{
internal static Injected<CustomContentAreaRenderer> _customContentAreaRenderer;
public static void RenderCustomContentArea(this HtmlHelper htmlHelper, ContentArea contentArea)
{
_customContentAreaRenderer.Service.Render(htmlHelper, contentArea);
}
}

That’s it!  If you look in the attached website you can view the test page and the text block will not be wrapped in two divs. Enjoy 🙂

Code Example

You can find a full code example here: https://github.com/jondjones/EpiCustomContentArea

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

5 replies
  1. Theo
    Theo says:

    Hi, Jon! First of all, thanks for the great help you give us with your blog.
    I have a question to ask, how can i render a block with a different html tag when it is among others in the same content area?
    The result would to look like this:

    <div class=""…
    <div class=""…
    <section class=""…
    <div class=""…
    <div class=""…

    Reply

Trackbacks & Pingbacks

  1. […] Handily for us EpiServer provides some extra overloads we can add into our PropertyFor helper to change the tags. If you are reading this and you really hate the idea of extra tags you can read my other tutorial : Extra divs in content area how to remove them ?. […]

  2. […] Handily for us EpiServer provides some extra overloads we can add into our PropertyFor helper to change the tags. If you are reading this and you really hate the idea of extra tags you can read my other tutorial : Extra divs in content area how to remove them ?. […]

  3. […] on top and below it. This unfortunately usually pushes styling out. I have written a blog post EpiServer 7 : Extra div’s in content area how to remove them ?. If you do not want to follow that approach the next best solution is to simply add them into the […]

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 *