Blocks, block types and block templates are linked together in the following way:
- A block type defines a set of properties, for example a heading and a page listing.
- A block is an instance of the .NET class defining the block type.
- As for pages, associated controllers, views and templates are used to render the block in some context.
Blocks can only be rendered in the context of other content, such as a page. A block instance is either part of a page instance if a PageType or BlockType contains a property of the block type, or a shared instance.
- For a page instance, the block is stored, loaded, and versioned as part of the page.
- For a shared block, the block is stored, loaded and versioned individually as an own entity, and can be referenced from multiple pages or blocks.
Block types
In Episerver, block types are usually defined in code as classes based on a model inheriting from EPiServer.Core.BlockData, in a similar fashion as for page types. During initialization, the bin folder is scanned for .NET classes inheriting BlockData. The BlockData object is the programmatic representation of a block, containing the properties defined in your .NET class. The value of currentBlock is automatically set to the BlockData object that is requested by the client.
For each of the classes found a block type is created. For all public properties on the class, a corresponding property on the block type is created.
Creating a block type
Using the Episerver Visual Studio integration, you create a block type by adding the Episerver Block type item to the Blocks subfolder under Models in your project. See Get started with Episerver CMS for more information.
Example: A simple block type with properties for a heading and a link 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, a unique GUID for the block type will automatically be generated when creating block types using the Episerver Visual Studio extensions.
Blocks will only be editable from the All Properties edit view, and can only be previewed in context of some other content like a page. However, you can add specific preview rendering for blocks, for editors to be able to 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, rendering of blocks is done by using controllers, views and associated templates, similar to the way you render pages.
- Create a controller that inherits from EPiServer.Web.Mvc.BlockController<TBlockData>, where TBlockData is your block type. The system calls this controller for the block type, if it is chosen as the renderer of 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 the view is chosen as the renderer of the block type, the view is called with the page data object directly, without controller involvement. This approach is the recommended way to render blocks.
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.
Creating 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 the Views/Shared folder of your project.
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>
Using templates
As for page types, templates can also be used to specify how blocks will be 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 initalization module, to register templates. See Rendering and the CMS sample site for examples.
Shared blocks folders
As previously mentioned, shared blocks are stored, loaded and versioned individually as an own 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 therefore 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 that are available for an editor. The global folder root EPiServer.Core.SiteSettings.Current.GlobalBlocksRoot, is the root folder for shared blocks that are 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.
Related topic
Do you find this information helpful? Please log in to provide feedback.