Exam Area: Content Area 1 – Product Knowledge (15%)
Reference: https://docs.developers.optimizely.com/content-management-system/docs/blocks
Blocks are small, reusable pieces of content. They allow editors to create content once and use it across multiple pages.
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.DataAnnotations;
using System.ComponentModel.DataAnnotations;
namespace MyOptimizelySite.Models.Blocks
{
[ContentType(
DisplayName = "Teaser Block",
GUID = "38d57768-e09e-4da9-90df-54c73c61b270",
Description = "Heading and image teaser.")]
public class TeaserBlock : BlockData
{
[CultureSpecific]
[Display(Name = "Heading", Order = 1, GroupName = SystemTabNames.Content)]
public virtual string Heading { get; set; }
[Display(Name = "Description", Order = 2, GroupName = SystemTabNames.Content)]
public virtual XhtmlString Description { get; set; }
[Display(Name = "Image", Order = 3, GroupName = SystemTabNames.Content)]
public virtual ContentReference Image { get; set; }
[Display(Name = "Link", Order = 4, GroupName = SystemTabNames.Content)]
public virtual Url Link { get; set; }
}
}
@* Views/Blocks/TeaserBlock.cshtml *@
@model TeaserBlock
<div class="teaser-block">
@if (!string.IsNullOrEmpty(Model.Heading))
{
<h3>@Html.PropertyFor(m => m.Heading)</h3>
}
@if (Model.Image != null)
{
<img src="@Url.ContentUrl(Model.Image)" alt="@Model.Heading" />
}
<div class="description">
@Html.PropertyFor(m => m.Description)
</div>
</div>
// In a Page type
[ContentType(DisplayName = "Article Page", GUID = "...")]
public class ArticlePage : PageData
{
// Block instance (inline) - stored with the page
[Display(Name = "Hero Block", Order = 10)]
public virtual HeroBlock HeroSection { get; set; }
// List of blocks (ContentArea)
[Display(Name = "Main Content", Order = 20)]
public virtual ContentArea MainContentArea { get; set; }
}
ContentArea is a special property that allows editors to drag and drop multiple blocks into it.
// Property type
public virtual ContentArea MainContentArea { get; set; }
@* Render ContentArea in View *@
@Html.PropertyFor(m => m.MainContentArea)
@* Or with custom display options *@
@Html.PropertyFor(m => m.MainContentArea, new { Tag = "wide" })
// Startup.cs / Initialization
services.Configure<DisplayOptions>(options =>
{
options
.Add("full", "Full Width", "u-full-width", string.Empty, "epi-icon__layout--full")
.Add("half", "Half Width", "u-half-width", string.Empty, "epi-icon__layout--two-columns");
});
| Feature | Shared Block | Page Block (inline) |
|---|---|---|
| Storage location | Assets Pane | Together with the page |
| Reusability | Multiple pages | Only 1 page |
| Versioning | Independent | Shares version with page |
| Editing | All Properties | All Properties |
// Controller for block (ViewComponent or Controller)
public class TeaserBlockComponent : BlockComponent<TeaserBlock>
{
protected override IViewComponentResult InvokeComponent(TeaserBlock currentBlock)
{
return View(currentBlock);
}
}
// Allow block preview in Edit View
[TemplateDescriptor(
Tags = new[] { RenderingTags.Preview },
TemplateTypeCategory = TemplateTypeCategories.MvcPartialView)]
public class TeaserBlockPreview : IView
{
// ...
}
BlockData)ContentArea? (A property that allows drag-and-drop of multiple blocks)[ContentType] inheriting from BlockData)