<head> driven by Content Area

For some powerful sites and editors sometimes it's wise to give them power to manipulate some stuff in <head> area. One of the simplest way to give editors this possibility is to create ContentArea where editors could create particular set of available blocks that would output themselves between <head> elements.

By default EPiServer will generate wrapping element around content area (div tag name is actually controllable as well, more info here):

@Html.PropertyFor(m => m.PageHeaderArea)

Resulting in:

<div>                 <!-- CA wrapper element -->  
    <div ...>         <!-- Block element -->
        <...>         <!-- Actual content of the block -->
    </div>
</div>  

EPiServer gives you an option to skip wrapper element generation - resulting only in set of blocks added to the content area.

@Html.PropertyFor(m => m.PageHeaderArea, new { HasContainer = false })

Resulting in:

<div ...>         <!-- Block element -->  
    <...>         <!-- Actual content of the block -->
</div>  

However, we still see that wrapping <div> element is not desired in <head> area.

Looking for the best place to add feature to skip even further - not to generate block wrapping element, but only content of the block itself.. Found that Twitter Bootstrap aware ContentAreaRender could be a perfect spot for new functionality.

So with latest version (v3.3.3) you can now write markup something like shown below.

UPDATE! You need to use HasEditContainer = false to avoid rendering edit container for the ContentArea. Otherwise you may end up with invalid markup that <head> element contains <div> elements inside.

@Html.PropertyFor(m => m.PageHeaderArea,
                  new
                  {
                      HasContainer = false,
                      HasItemContainer = false,
                      HasEditContainer = false
                  })

Resulting in:

<...>         <!-- Only actual content of the block -->  

Use Case - Meta Data Block

One of the use cases we had - to give editors possibility to add minifest files for the page by themselves.

So markup for the block is pretty straight forward:

@model DynamicMenu.Models.Blocks.MetaDataBlock

<link rel="@Model.RelationshipName" href="@Url.ContentUrl(Model.Link)">  

ContentArea definition for the start page:

public class StartPage : PageData  
{
    [AllowedTypes(typeof(MetaDataBlock))]
    public virtual ContentArea HeaderContentArea { get; set; }
}

Then in _SiteLayout.cshtml (or any other layout page where you define <head>) you can write:

<html>  
<head>  
    @Html.PropertyFor(m => startPage.HeaderContentArea,
                      new {
                            HasContainer = false,
                            HasItemContainer = false,
                            HasEditContainer = false
                          })
    ...

Resulting in:

<html>  
<head>  
    <link rel="manifest" href="http://someserver/somefile.json">
    ...

Happy heading!
[eof]

wałdis iljuczonok

Software architect, lead technologist and Visual Studio ALM & TFS evangelist, technical fellow. Focus on solution research, new technologies analysis and enterprise designing.

https://tech-fellow.net
riga.lv

comments powered by Disqus