Content types in code
Explains the concept of content types and templates, and how these are associated in Optimizely CMS.
NoteThe examples in this topic are based on ASP.NET Core.
Content, content types, and content templates are linked together in the following way:
- A content type defines a set of properties, for example, name and publish date.
- A content instance is an instance of the .NET class defining the content type. When a content instance is created in edit page, values are assigned to the properties and stored in the database.
- A template (for example, an MVC controller) fetches the stored property values and renders the output.
- A template is associated with the content type to render the output in a certain context.
As shown in Content, there are several different base types or categories of content, like pages, blocks, and media in Optimizely CMS. Other products, like Optimizely Customized Commerce, have their base types of content. A specific implementation then creates several content types from the different content base types.
The following sections provide examples of how to model content types. Content templates describes how different content types are rendered.
NoteStandard MVC routing is not registered by default by CMS, but if it is used, renaming of a controller or action affects the URL or route to the action.
Content types
Content types give editors a structured way to create and manage specific kinds of content.
In CMS, content types are usually defined in code as .NET classes inheriting from IContentData (or a suitable base class implementing IContentData like PageData) and decorated with ContentTypeAttribute. There are different content base types in CMS, such as pages (base class EPiServer.Core.PageData), blocks (base class EPiServer.Core.BlockData), and media (interface EPiServer.Core.IContentMedia).
To add a content type to CMS, add a .NET class to the project, inheriting the appropriate base class or interface (for pages, for example, PageData) and decorate the class with ContentTypeAttribute. During initialization, the assemblies are scanned for .NET classes attributed with ContentTypeAttribute. For each of the classes found, a content type is created. For all public properties on the class, a corresponding property on the content type is created. The content type is then available for editors to create an instance of.
NoteThe
Nameproperty ofContentTypeAttributemust follow this pattern:^[A-Za-z][_0-9A-Za-z]+and be between two and 255 characters. Invalid names cause content type registration to fail during initialization.
Create a content type
See Get started with CMS for information about creating a CMS project.
To add properties for all page types (content types of base type PageData), add an abstract SitePageData base class, which inherits from EPiServer.Core.PageData. This base class has an SEO property used on all pages inheriting from the class.
The following example shows a simple article page type with a "Main Body" editor area of the property type XhtmlString type, inheriting from the SitePageData base class.
using System;
using System.ComponentModel.DataAnnotations;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.DataAnnotations;
using EPiServer.SpecializedProperties;
namespace MyOptimizelySite.Models.Pages {
[ContentType(DisplayName = "ArticlePage", GUID = "b8fe8485-587d-4880-b485-a52430ea55de", Description = "Basic page type for creating articles.")]
public class ArticlePage: SitePageData {
[CultureSpecific]
[Display(
Name = "Main body",
Description = "The main body editor area lets you insert text and images into a page.",
GroupName = SystemTabNames.Content,
Order = 10)]
public virtual XhtmlString MainBody {
get;
set;
}
}
}The following example shows the SitePage base class with the SEO property.
namespace MyOptimizelySite.Models.Pages {
public abstract class SitePageData: EPiServer.Core.PageData {
[Display(GroupName = "SEO", Order = 200, Name = "Search keywords")]
public virtual String MetaKeywords {
get;
set;
}
}
}Assign a unique GUID for the ContentTypeAttribute for all types to support renaming or moving the class later. Content types implicitly contain a set of built-in properties available for all content instances, regardless of the content type instance. See Content Metadata properties for built-in metadata properties.
Because the rendering template has not yet been created, pages based on this page type cannot be edited from the On-Page edit page, only from the Visual Builder or All Properties edit pages.
NoteProperties are declared as
virtualbecause a proxy class is created for the page type. The proxy overrides the properties with an implementation, and this only works if properties are declared as virtual. If the properties are not declared virtual, implement get and set so that these read and write data to the underlying property collection instead.
Custom content base types
Custom content base types let you define content structures beyond the standard page, block, and media types.
When creating a content type, it is usually based on an existing base type (like PageData, BlockData, IContentMedia, and so on). The content type is then automatically available in edit page. For example, pages are available for creation from the page tree, while blocks and media are created from the assets panel. Define a custom content type that is not based on any existing base type, like in Persisting IContent instances. A custom-defined content type that does not belong to a known base type is not available to create from edit page by default. This is acceptable if the usage is only programmatic, but if you want a custom-based content type to be available in edit page, extend the UI. See Describe content in the UI for an example of extending the UI for additional content roots.
NoteIn CMS 13,
PageReferenceis obsolete. UseContentReferencefor all content reference properties and return types.
Blocks
Blocks let editors add reusable content parts to pages, making it easier to maintain consistent layouts.
Blocks in CMS differ from other content types in that they are reusable smaller content parts, which editors add to pages. Use blocks or lists of blocks in code as an instance or list property on a content model (for example, a page). This section explains the concept of blocks, block types, and templates.
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.
- Associated view components and views render the block in some context.
Blocks are only rendered in the context of other content, such as a page. A block instance is part of a content instance (if a ContentType contains an instance or list property or a list of the block type), or a shared instance.
- For an instance or list instance or list property on a content instance, the blocks are stored, loaded, and versioned as part of the content instance.
- For a shared block, the blocks are stored, loaded, and versioned individually as an entity, and are referenced from multiple pages or blocks.
Block types
Block types define the properties and structure of reusable content blocks.
In CMS, 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 assemblies are scanned for .NET classes inheriting BlockData and decorated with ContentTypeAttribute. 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 the client requests.
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.
Create a block type
The following example shows 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 MyOptimizelySite.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, assign a unique GUID for the block type to support future renaming.
Blocks are editable from the Visual Builder or All Properties edit page, and are only previewed in the context of some other content like a page. Add specific preview rendering for blocks to let editors edit and preview them in the On-Page edit page.
Updated 18 days ago
