Your First ContentItem

Your First ContentItem

Let's create a simple page type. We'll call this a TextPage, and as such we will create a corresponding class called TextPage. This is what TextPage looks like:

using N2.Details;
using N2.Integrity;
using N2.Definitions;
using System;
public class TextPage : ContentItem
{
}

By default, N2 inherits a few properties and methods from ContentItem. Here are a few of particular interest (don't worry about the details for now):

  • public virtual DateTime Created { get; set; }
  • public virtual string IconUrl { get; }
  • public virtual bool IsPage { get; }
  • public virtual IList<T> GetChildren<T>() where T : ContentItem
  • public virtual IList<T> GetChildren<T>(string zoneName) where T : ContentItem
  • public virtual string TemplateUrl { get; }
  • public virtual string Title { get; set; }
  • public virtual DateTime Updated { get; set; }
  • public virtual string Url { get; }
  • public virtual int VersionIndex { get; set; }

Note that none of these methods are abstract. Thus, you can see that N2 does a lot of the work for you. N2 takes care of versioning, managing URLs (though you can customize them), children, templates, modification and creation times, and more. Also note that all of these methods and properties are virtual; thus, you can override any of them in your own subclass to completely customize N2 to your exact needs. We won't do any customization right now, but we did want to point out this highly flexible engineering model.

Make it a Page

In N2, every piece of content -- whether it's a page, part, or data entity -- is a ContentItem. Therefore, we need to let N2 know that we actually want to create a page. Pages in N2 implement the IPage interface, which is simply a marker interface. In other words, IPage doesn't actually define any methods or properties.  Note: At this point we've basically built AbstractPage, which is a base class for all pages used in the Webforms template pack.

Defining Additional Properties

Any properties that we want to expose through our Views (which we'll see how to create in a bit), we need to define on our own. Let's define:

  • a title
  • some textual (body) HTML content
  • an optional header image

Now for the image:

[FileAttachment, EditableFileUploadAttribute("Image", 90, ContainerName = Tabs.Content, CssClass = "main")]
public virtual string Image
{
	get { return (string)(GetDetail("Image") ?? string.Empty); }
	set { SetDetail("Image", value, string.Empty); }
}

Exposing Properties through Editors

Now that we've defined our properties, we will decorate them with C# attributes that tell N2 how to handle the properties. For example, N2 can automatically generate editors to be used in the Edit interface. (We'll discuss the Edit interface in more detail in the next topic)

ContentItem Editor Hierarchy

Figure 1. Editors are exposed via attributes on the properties defined in ContentItems.

Creating the View

The ContentItem tells N2 everything about the data that needs to be stored for a given item in N2's database. However, it does not define how the ContentItem will look when N2 generates a HTML page. We will cover Creating the View in a later chapter; the actual implementation of the view will differ depending upon the view framework we're using (either MVC or WebForms). However, the content model (ContentItem) remains the same.


 

  • Since TextPage inherits from N2.ContentItem (in this case a bit down the inheritance chain) it is treated by the N2 engine as a content type and made available for editing through the edit interface.
  • Take a quick look at that Text property before you move on. It has an interesting attribute that's used by the N2 engine to determine what kind of editor should be used to edit that property.

A property encapsulating our content

First, lets examine that attribute called EditableCheckbox. The attribute tells the N2 engine that this is a property that is editable in edit mode. Since it's the EditableCheckbox attribute a textarea is displayed when you edit this page. The parameters are just the name displayed in edit and the order of this property.

There are a number of built-in "editable" attributes. For more information, see the Editors chapter in the user guide.

Note the call to GetDetail in the getter. GetDetail gets values from a content detail collection and SetDetail updates the same value. Any serializable class is supported. The content detail collection contains all custom properties.