One of the first things you'll do when starting a new Redakt project is defining page and content (view) models. These models determine which content & properties are available for editing by your content managers on your pages and library assets.

Most content management systems store these definitions in a database. Redakt has a code-first approach for content models. This means that content models are part of your application code instead. They are used as strongly typed models in your views and will be deployed together with the rest of your application.

Defining content models

Content models are created as POCO classes in your codebase. All content model classes must implement the IContentType interface, or derive from a base class that implements it. The IContentType interface does not contain any properties or methods to implement itself, but it serves as a marker interface for the system to recognize the class as a content model. It does not matter in which namespace or assembly the page model is located; the system will register all content models in your project on startup by assembly scan. You can even put your content models in a separate shared project for re-use in other applications.

Content model types are part of the larger Redakt content management object hierarchy. It's important to understand the relation between these different objects. We recommend you also read the article on the content management object hierarchy.

Content model classes determine the following aspects of content creation and editing:

  • the type of content item, i.e. page, asset, folder, or nested content;
  • the properties (and their behavior) that are available for editing in the back office;
  • the type of editor component that is used for properties in the back office;
  • the validation rules for property values;
  • the hierarchy of allowed content types (which type can be child content of this content item);
  • the views that are allowed for the content type;

See further below on this page for some examples of content model classes. These example also contain several other class and property attributes that define the behavior of a model. See the complete list of class and property attributes for the use of these and other attributes.

Content model node types

In its simplest form, a content model is a class with properties that are editable in the back office application. However, within the larger content hierarchy, Redakt needs to know where content based on this model may be created.

Redakt content is contained within a node hierarchy (tree). Each node is part of a node collection. A node collection can be a website or an asset library. Multiple websites and asset libraries can exist within a single Redakt system. Website and asset library node collections are technically very similar. The only difference is the node types that are allowed to be created within the node collection: website node collections can contain only page node types, and asset library node collections can contain asset and folder node types.

Different node types behave differently in the back office application. So when defining content models, first of all, we need to specify what type of node the content model is for. Content models can also be nested within another content model, in which case the content model does not have a node type at all.

You specify the node type of the content model by decorating the class with a specific node type attribute:

  • Pages (in a website) - decorate with PageAttribute
  • Assets (in an asset library) - decorate with AssetAttribute
  • Folders (in an asset library) - decorate with FolderAttribute
  • Nested content (part of a page or asset model) - do not decorate with a node type attribute

Content models that are not explicitly marked with a node type attribute cannot be used to create new nodes and are assumed to be nested content model types by default.

Page

Pages are part of a website and can be published to a URL. For content intended to be used for a page, decorate the content model class with the PageAttribute. Below is an example of what a page content model could look like.

[Page]  // <-- the attribute that identifies this class as a page node type
[Icon(ContentIcons.FileText)]
[AllowChildren(typeof(ContentPage), typeof(BlogArticle))]
[AllowView("ContentPage")]
[DefaultSection("Content")]
public class ContentPage : IContentType
{
    [Required]
    [CultureDependent]
    public string PageTitle { get; set; }

    [Section("Heading")]
    [DisplayName("Caption")]
    [CultureDependent]
    public string HeadingCaption { get; set; }

    [DisplayName("Description")]
    [Multiline]
    [CultureDependent]
    public string PageDescription { get; set; }

    [Section("Modules")]
    [HideLabel]
    [HelpText("Add content modules here.")]
    public IReadOnlyList<ModuleBase> Modules { get; set; }
}

Asset

Assets (f.e. images or documents) are contained in an asset library. For content intended to be used for an asset, decorate the content model class with the AssetAttribute. Below is an example of what an asset content model could look like.

[Asset]  // <-- the attribute that identifies this class as an asset node type
[Icon(ContentIcons.FileImageLandscape)]
[MediaUpload]
public class Image: IContentType
{
    [AcceptMimeType("image/jpeg", "image/gif", "image/png", "image/bmp", "image/tiff", "image/svg+xml")]
    [Section("Image")]
    public Media File { get; set; }

    [Section("Image")]
    [CultureDependent]
    public string AlternateText { get; set; }
}

Folder

Folders are containers for assets inside an asset library. Even though folders generally don't have any content that can be managed (although they can), they still need to have an (empty) content model class created for them, in order to make the folder available to the system. Decorate folder content model classes with the FolderAttribute. Below is an example of what a folder content model could look like.

[Folder]  // <-- the attribute that identifies this class as a folder node type
[AllowAtRoot]
[AllowChildren(typeof(MediaFolder), typeof(Image), typeof(Video), typeof(Document))]
[Icon(ContentIcons.FolderImage)]
public class MediaFolder: IContentType
{
    // No actual content properties
}

Nested content

Nested content is content that is not directly part of the hierarchy of a site or asset library, but is contained within another content item as content values. For example, a frequently-asked-questions page content model will have nested question/answer content models. Content models that are to be used as nested content are not decorated with a node type attribute. By default, all content models are nested content models unless decorated with one of the node type attributes mentioned above.

[Icon(ContentIcons.Question)]
public class FrequentlyAskedQuestion: IContentType
{
    public string Question { get; set; }

    [Multiline]
    public string Answer { get; set; }

    public Image IconImage { get; set; }
}

Model attributes

Further content model configuration and behavior is also set through decorating the class and its properties with attributes. All attributes are optional, and a default configuration will be set by convention. Click on the links below for a complete list of attributes that content models may be decorated with.

  • Class attributes determine the configuration and behavior of the content model as a whole.
  • Property attributes determine the configuration and behavior of the individual properties on the content model.
  • Property editor attributes determine the configuration and validation of property editors in the back office.

Model inheritance

You can inherit a content model from another (abstract) content model. The derived content model will inherit all properties from the base class, and add its own properties. For example, the following model will have all the properties of the ContentPage model, and adds an ExtraContent nested content section.

[AllowChildren(typeof(ContentPage), typeof(NewsPage))]
public class NewsPage: ContentPage
{
    public ExtraContent Extra { get; set; }
}

When setting allowed child models with the AllowChildren attribute, any derived models that may be used as child models have to be allowed explicitly. Therefore in the example above, the NewsPage model has to be allowed explicitly, even though the ContentPage is already included, which is a base class of the NewsPage model.

Property Editors

When editing content in the back office user interface, each model property has a specific property editor that is used to edit that property's value or values. In most cases, the system will select the correct default property editor by convention. For example, for string properties, a textbox editor is displayed in the user interface, and for boolean properties a checkbox is displayed. However in some cases you may want to select a different editor than the default one, for example you may want to display a dropdown select list instead of a textbox for a string property. To select a specific property editor, and for property editor behavior & configuration settings, read more in the property editor section.