How do I make a block editable with on page editing?

  • Page Owner: Not Set
  • Last Reviewed: 2020-08-21

What do I need to make a block editable with on-page-editing in Episerver?


Answer

This is how we typically do it:

Create an IPreviewableBlock interface:

public interface IPreviewableBlock { }

For any block you want to make on-page-editable, implement IPreviewableBlock

public class RichTextBlock : BlockData, IPreviewableBlock {
}

Add a controller for preview blocks that is the default renderer for IPreviewableBlock with the Preview tag:

[TemplateDescriptor(Tags = new[] { RenderingTags.Preview }, TemplateTypeCategory = TemplateTypeCategories.MvcController, Inherited = true)]
public class PreviewableBlockController : Controller, IRenderTemplate<IPreviewableBlock>
{
    public ActionResult Index(BlockData currentContent) => View("~/Views/Shared/BlockPreview.cshtml", currentContent);
}

Then add the BlockPreview.cshtml view. Make sure you override the Layout, otherwise it may use the site surround template, which will lead type errors as Episerver will send your block as the model, but the site surround is expected IPageViewModel or something similar.

@model EPiServer.Core.BlockData
@{
    Layout = null;
}

<html>
    <head>
        <title>Block Preview</title>
        <!-- Fill this stuff in with real site styles so the block renders properly in preview mode -->
    </head>
    <body>
        @{
            Html.RenderContentData(Model, false, Constants.DisplayTags.BlockEdit);
        }
    </body>
</html>

You want this to basically match the site surround, but without the stuff that relies on IPageViewModel.

Finally, create an edit-mode friendly view. This can either be your default view, or if you want an edit-mode specific view, you can register a view with the BlockEdit tag (or whatever you call the tag in the Constants.DisplayTags.BlockEdit above).

RegisterBlock<RichTextBlock>(BlockEdit);

A BlockEdit view can also be useful if your block uses a controller / view model. The preview won't use your controller, so you can use a BlockEdit tagged view that accepts the block model directly, instead of the view model.