HomeDev GuideRecipesAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Preview rendering for blocks

Describes how to create a view and controller for previewing blocks in Optimizely Content Management System (CMS).

The preview adds on-page editing functionality and a realistic view of the block's appearance when added to content areas with different widths.

Shared blocks are rendered in the context of a page, for example, inside a content area. Like pages, you can edit blocks in the All Properties editing view, but to preview and edit them in the On-page edit view, you can create a preview page to render blocks in edit view. A block template is typically a partial template like a partial MVC controller or a partial view. The rendering is using the built-in Preview tag in the EPiServer.Framework.Web namespace.

Create a block preview template

In this example, you create components to build a preview that you can use for all blocks:

  • A block preview page type
  • A block edit page view model
  • A preview controller
  • A preview view

See Page types and templates and Block types and templates for information on how to create page types, controllers, and views.

Block preview page type

Example: The block preview page type with a content area.

namespace MyEpiserverSite.Models.Pages {
  public class PreviewBlock: PageData {
    public IContent PreviewContent {
      get;
      set;
    }
    public ContentArea ContentArea {
      get;
      set;
    }

    public PreviewBlock(PageData currentPage, IContent previewContent): base(currentPage) {
      this.PreviewContent = previewContent;
      this.ContentArea = new ContentArea();
      this.ContentArea.Items.Add(new ContentAreaItem {
        ContentLink = this.PreviewContent.ContentLink
      });
    }
  }
}

Block edit page view model

Example: View model for the block.

📘

Note

The IPageViewModel is a pattern from the Alloy sample site and it not required if the site not based on Alloy.

namespace MyEpiserverSite.Models.ViewModels {
  public class BlockEditPageViewModel: IPageViewModel<SitePageData> {
    public BlockEditPageViewModel(PageData page, IContent content) {
      previewBlock = new PreviewBlock(page, content);
      CurrentPage = page as SitePageData;
    }
    public PreviewBlock previewBlock {
      get;
      set;
    }
    public SitePageData CurrentPage {
      get;
      set;
    }
  }
}

Preview controller

PreviewController inherits from the ActionControllerBase and implements IRenderTemplate<BlockData>, making the controller able to render block types. It overrides the Index method and gets the start page as rendering context. It creates an instance of the PreviewBlock page type, and programmatically adds the block to the content area. The controller has a TemplateDescriptor "Preview" tag, ensuring that it is used for on-page editing only.

Example: The preview controller. If the site is using dependency injection, change this example to take the IContentLoader dependency as constructor injection instead.

namespace MyEpiserverSite.Controllers {
  [TemplateDescriptor(Inherited = true,
    TemplateTypeCategory = TemplateTypeCategories.MvcController,
    Tags = new [] {
      RenderingTags.Preview, RenderingTags.Edit
    },
    AvailableWithoutTag = false)]

  public class PreviewController: ActionControllerBase, IRenderTemplate<BlockData>

    {
      public ActionResult Index(IContent currentContent) {
        var contentLoader = ServiceLocator.Current.GetInstance<IContentLoader>();
        var startPage = contentLoader.Get<PageData>(ContentReference.StartPage);
        var model = new BlockEditPageViewModel(startPage, currentContent);
        return View(model);
      }
    }
}

Preview view

Example: View for rendering the block in different widths depending on context.

@model MyEpiserverSite.Models.ViewModels.BlockEditPageViewModel
    
    <div class="row">
      <div class="span12">
        @Html.PropertyFor(m => m.previewBlock.ContentArea)
      </div>
    </div>
    
    <div class="row">
      <div class="span8">
        @Html.PropertyFor(m => m.previewBlock.ContentArea)
      </div>
    </div>
    
    <div class="row">
      <div class="span4">
        @Html.PropertyFor(m => m.previewBlock.ContentArea)
      </div>
    </div>

When editing and previewing a block in edit view, the resulting outcome looks like this.