How to render all your block variations in preview mode in Episerver

I’ve talked previously about how to preview blocks in Episerver, How to Preview a Block in Episerver.  In today’s tutorial we are going to cover previewing different renderings for your blocks based on all the available display options set on the website.

episerver_display_options_dialog

In this advanced tutorial we’ll cover a preview model to render all these variations, like so:

preview_blocks_editor

I’ve talked previously about display options and I’m assuming you have all that bit set-up.  If you go to the end of this tutorial you can download a working code example with both preview and display options enabled.

The Preview Controller

The first thing we need to do is create a preview controller.  This is the controller that will get called when we try to preview a block in the editor.

[TemplateDescriptor(Inherited = true,
Tags = new[] { RenderingTags.Preview },
TemplateTypeCategory = TemplateTypeCategories.MvcController)]
public class PreviewController : Controller, IRenderTemplate<BlockData>
{
private readonly DisplayOptions displayOptions;
private readonly TemplateResolver templateResolver;
private readonly IEpiserverDependencies epiDependencies;
private IContent currentContent;
public PreviewController(DisplayOptions displayOptions, TemplateResolver templateResolver, IEpiserverDependencies epiDependencies)
{
this.displayOptions = displayOptions;
this.templateResolver = templateResolver;
this.epiDependencies = epiDependencies;
}
public IEpiserverDependencies EpiserverDependencies
{
get { return epiDependencies; }
}
public ActionResult Index(IContent currentContent)
{
this.currentContent = currentContent;
var startPage = epiDependencies.ContentRepository.Get<StartPage>(SiteDefinition.Current.StartPage);
var supportedAreas = GetSupportedPreviewAreas();
var viewModel = new PreviewViewModel(startPage, currentContent, supportedAreas);
return View("~/Views/Blocks/Preview.cshtml", viewModel);
}
private IEnumerable<PreviewArea>()
{
return displayOptions.Select(x => new PreviewDisplayOption
{
Tag = x.Tag,
Name = x.Name,
IsSupported = IsTagSupported(currentContent, x.Tag)
})
.Where(x => x.IsSupported)
.Select(CreatePreviewArea);
}
private PreviewArea CreatePreviewArea(PreviewDisplayOption previewDisplayOption)
{
var contentArea = new ContentArea();
var item = new ContentAreaItem
{
ContentLink = currentContent.ContentLink
};
contentArea.Items.Add(item);
var areaModel = new PreviewArea
{
ContentArea = contentArea,
Supported = previewDisplayOption.IsSupported,
AreaTag = previewDisplayOption.Tag,
AreaName = previewDisplayOption.Name,
};
return areaModel;
}
private bool IsTagSupported(IContent content, string tag)
{
var templateModel = templateResolver.Resolve(HttpContext,
content.GetOriginalType(),
content,
TemplateTypeCategories.MvcPartial,
tag);
return templateModel != null;
}
}

There’s quite a lot of code here so we’ll start a method at the time.

  • GetSupportedPreviewAreas: In the constructor we get Episerver to pass in all the available display options. In this method we iterate through each one of the display options and create a preview area for it.
  • CreatePreviewArea: In here we build up a PreviewArea. The Preview Area will eventually be passed on down to the view so it will contain all the information we need about the block. We create our own content area.

The Preview View Model

public class PreviewViewModel : BaseViewModel<StartPage>
{
public PreviewViewModel(StartPage currentPage, IContent previewContent, IEnumerable<PreviewArea> areas)
: base(currentPage)
{
this.PreviewContent = previewContent;
this.Areas = areas.ToList();
}
public IContent PreviewContent { get; private set; }
public IList<PreviewArea> Areas { get; private set; }
}

In the view model we pass in a reference to the start page and the list of Preview Areas we created.

The Preview View

@model JonDJones.com.Core.ViewModel.Base.PreviewViewModel
@{
Layout = "~/Views/Shared/PreviewLayout.cshtml";
}
@foreach (var area in Model.Areas)
{
if (area.Supported)
{
@Html.Partial("TemplateHint", string.Format(@Html.Translate("/preview/heading"), Model.PreviewContent.Name, area.AreaName))
<div class="row preview clearfix">
@Html.DisplayFor(x => area.ContentArea, new { Tag = area.AreaTag })
</div>
}
else
{
@Html.Partial("TemplateHint", string.Format(@Html.Translate("/preview/norenderer"), Model.PreviewContent.Name, area.AreaName))
}
}
@if (!Model.Areas.Any())
{
@Html.Partial("TemplateHint", string.Format(@Html.Translate("/preview/norendereratall"), Model.PreviewContent.Name))
}

We’ll use the same preview layout from the last tutorial, the only difference now is we need to define a custom TemplateHint.  The template hint is the little hint that gets displayed in the
.

TemplateHint

@model string
<p class="alert alert-info">@Model</p>

Conclusion

In today’s tutorial we’ve covered quite a lot of code.  We’ve extended on How to Preview a Block in Episerver but this time we’re using the different display options to render all the different variations of the block.

I’ve talked previously about how to set-up Episerver to render blocks differently based on the display options, How To Make A Block Use Multiple Views ? A Partial View Controller Explained .  On this preview we also render every display option in the view.

Additionally, we also implemented our own TemplateHint to make the little hint that appears in the preview.

Code Sample

All the above code can be downloaded in a fully working website from my github account here.

EpiserverDisplayOptionsAndPreview

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

0 replies

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 *