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

Block types and templates

Describes the concept of blocks, block types and templates, and how these are associated. It also describes how to create a simple block type with rendering.

Blocks in Optimizely Content Management System (CMS) are reusable, smaller content parts that editors can add to pages. You can also use blocks in code as properties. 

📘

Note

The examples here are based on MVC.

Optimizely Content Management System (CMS) relates blocks, block types, and block templates in the following ways:

  • A block type defines a set of properties, such as a heading and a page listing.
  • A block is an instance of the .NET class defining the block type.
  • As for pages, use associated controllers, views and templates to render the block in some context.

You can render blocks only in the context of other content, such as a page. A block instance is part of a page instance if a PageType or BlockType contains a property of the block type or a shared instance.

  • A page instance stores, loads, and versions a block as part of the page.
  • A shared block loads and versions a block individually as an entity and references from multiple pages or blocks.

Block types

In Optimizely Content Management System (CMS), you usually define block types in code as classes based on a model inheriting from EPiServer.Core.BlockData, in a similar fashion as for page types. During initialization, CMS scans the bin folder for .NET classes inheriting BlockData. The BlockData object is the programmatic representation of a block containing the properties defined in your .NET class. CMS automatically sets the value of currentBlock to the BlockData object that the client requests. 

CMS creates a block type for each class found and creates a corresponding property on the block type for public properties on the class.

Create a block type

Using the Visual Studio extension, you create a block type by adding the Block type item to your project's Blocks subfolder under Models. See Get started with Optimizely Content Management System (CMS 11).

Example: A simple block type with properties for a heading and links to an image. TeaserBlock inherits from BlockData, which inherits from EPiServer.Core.BlockData.

using System;
using System.ComponentModel.DataAnnotations;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.DataAnnotations;
using EPiServer.Web;

namespace MyEpiserverSite.Models.Blocks {
  [ContentType(DisplayName = "TeaserBlock",
    GUID = "38d57768-e09e-4da9-90df-54c73c61b270",
    Description = "Heading and image.")]
  public class TeaserBlock: BlockData {
    [CultureSpecific]
    [Display(Name = "Heading",
      Description = "Add a heading.",
      GroupName = SystemTabNames.Content,
      Order = 1)]
    public virtual String Heading {
      get;
      set;
    }

    [Display(Name = "Image", Description = "Add an image (optional)",
      GroupName = SystemTabNames.Content,
      Order = 2)]
    public virtual ContentReference Image {
      get;
      set;
    }
  }
}

As for page types, CMS automatically generates a unique GUID for the block type when creating block types using the Visual Studio extension.

You can edit blocks only from the All Properties edit view. You can also preview them only in the context of some other content, like a page. However, you can add specific preview rendering for blocks for editors to edit and preview them in the On-Page edit view.

📘

Note

Why are the properties declared as virtual here? What happens in the background is that a proxy class is created for the block type, and data is loaded from the database to a property carrier (Property), receiving the data. Through Castle (Inversion of Control tool), the properties in the proxy block type will be set, and this only works if properties are declared as virtual. If the properties are not declared virtual, you need to implement get/set so that these will read/write data to the underlying property collection instead.

Block controllers and views

In MVC, render blocks using controllers, views, and associated templates, similar to how you render pages. 

  • Create a controller that inherits from EPiServer.Web.Mvc.BlockController<TBlockData>, where TBlockData is your block type. If it chooses the renderer for the block type, it calls this controller for the block type. EPiServer.Web.Mvc.BlockController<TBlockData> has an implementation of the action Index, which calls a partial view with the same name as the block type.
  • Create a partial view without a controller, naming the view the same as the block type. If it chooses the view as the renderer of the block type, it calls the view with the page data object directly, without controller involvement. You should render blocks this way.

📘

Note

For performance reasons, it is recommended to use partial views directly, and not controllers, for block types. You can create a view to be used without a controller through naming convention in MVC.

Create a partial view

In Visual Studio, add a partial view with the same name as your block type and, based on your block model class, to your project's Views or Shared folder.

Example: The partial view for the TeaserBlock block type, displaying a heading and an image.

@model MyEpiserverSite.Models.Blocks.TeaserBlock
    
    <div>
      <h2>@Html.PropertyFor(x => x.Heading)</h2>
      <img src="@Url.ContentUrl(Model.Image)" />
    </div>

Use templates

As for page types, you can also use templates to specify how blocks are rendered in a specific context, for example, a content area or a display channel. Note that if you are using partial views and no controllers, you cannot implement the TemplateDescriptor. Instead, you can use the ViewTemplateModelRegistrator interface and an initialization module to register templates. See Rendering.

Shared blocks folders

As previously mentioned, CMS stores, loads, and versions shared blocks individually as an entity in the database. Shared blocks are structured using folders, and a Folder is an instance of EPiServer.Core.ContentFolder. Content folders do not have associated rendering and no visual appearance on the website.

A folder in the shared blocks structure can have other folders or shared blocks as children, and a shared block cannot have any children.

You set editorial access on folders to specify which folders are available for an editor. The global folder root EPiServer.Core.SiteSettings.Current.GlobalBlocksRootis the root folder for shared blocks available for sites in an enterprise scenario. There can be a site-specific folder EPiServer.Core.SiteSettings.Current.SiteBlocksRoot, containing the folder structure for shared blocks. In a single-site scenario, GlobalBlocksRoot and SiteBlocksRoot typically point to the same folder.