HomeGuidesAPI Reference
Submit Documentation FeedbackJoin Developer CommunityOptimizely GitHubOptimizely NuGetLog In

Preview rendering for blocks

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

This topic 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 what the block will look like when added to content areas with different widths.

How it works

Shared blocks are rendered in the context of a page, for example inside a content area. Like pages, blocks can be edited in the all properties editing view, but to be able to preview and edit them in the on-page edit view, you can create a preview page used 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 we created these components to build a preview that can be used 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. The Index method is overridden and gets the start page as rendering context. A new instance of the PreviewBlock page type is created, and the block is programmatically added to the content area. The controller has a TemplateDescriptor "Preview" tag, ensuring that it is only used for on-page editing.

Example: The preview controller. If the site is using dependency injection this example should be changed 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>

The resulting outcome when editing and previewing a block in edit view.