Introduction to the PageTypeBuilder project

This article was migrated from an older iteration of our website, and it could deviate in design and functionality.


An introduction to Joel Abrahamsson's PageTypeBuilder project for EPiServer. Here I go through the basics of defining a strongly typed page type including page type inheritance.

Estimated read time : 12 minutes

Jump to

Different approaches for enabling strongly typed EPiServer page types

EPiServer’s native approach

The default approach for managing EPiServer page types looks like this:

Flowchart for native EPiServer page type management

As you can see, the EPiServer GUI is used to manage page type definitions stored in the EPiServer database. For the sake of clarity, EPiServer does not natively offer strongly typed page types.

Our (previous) approach

In 2007 we had a little project called EPiPageTypes. It was based on the idea that page types are created through EPiServer’s admin interface. But, as a pre-build event in our projects we ran an executable which retrieved all page type definitions from the EPiServer database and generated a plain C# code file within the project with one class per page type which in turn contained one property per page type property.

In other words, if I created a page type called MyPageType which had an XHTML page property called MainBody I could access that property for the current page using this syntax:

string propertyValue = ((MyPageType)CurrentPage).MainBody;

Whenever the EPiServer website was compiled the source code for the page type classes were updated, so you’d get a compile-time error if a page type had been changed in EPiServer, for example if a page property had been renamed or removed. So, the model looked something like this:

Getting strongly typed page types using EPiPageTypes

However, there was one major thing we didn't accomplish with this, and that was page type inheritance. But, thanks to some truly excellent work by Joel Abrahamsson, we've gotten exactly that. Which brings me to the third approach…

Joel Abrahamsson’s Page Type Builder project

Joel, a systems architect at Valtech, is the guy behind the open-source project Page Type Builder. Not only does it result in strongly typed page types like our EPiPageTypes project, but it also allows for page type inheritance – something the EPiServer community has been wanting for quite some time.

So, in order to be consistent, here’s the idea behind the PageTypeBuilder project (notice how the arrows now point the other way):

Generating strongly typed page types using PageTypeBuilder

As you see, Joel’s approach starts from the other end: page type definitions are declared in code and through reflection the EPiServer database is updated when the application starts.

Erik Nordin has posted some code snippets for the project, but I thought I’d complement those with a brief demonstration of how to declare EPiServer page types through code and how to realize page type inheritance in EPiServer.

Using the Page Type Builder project with your EPiServer website

First of all you need to download the Page Type Builder project from CodePlex. You can download either a compiled version or the source code.

I opted for the source code and included the project in my EPiServer solution:

Solution explorer window

Note: to avoid having Visual Studio tell you the PageTypeBuilder project location isn’t trusted, or an exception saying That assembly doesn’t allow partially trusted callers, ensure you unblock the ZIP file before extracting the PageTypeBuilder files:

Properties for the downloaded PageTypeBuilder zip file

Next I added a reference to the PageTypeBuilder project in my website project called TedNyberg:

Solution explorer window

Add Reference dialog

Allright, now we’re able to access a whole box of goodies inside the PageTypeBuilder namespace!

Defining our first page type

I created an empty ASPX file called MyPageTemplate and made it inherit from the TemplatePage class, just like the default page templates in the EPiServer sample website:

Template file structure 

Next I created a class called MyPageType like so:

Declaring the MyPageType page type using PageTypeBuilder attributes

After logging in to the EPiServer admin interface I could now see this:

EPiServer page type list

Opening the settings for the My Page Type page type I could see that the settings applied through the PageTypeBuilder attributes have worked as expected:

Page type properties in EPiServer admin mode

Notice how the name, description and file name reflect the PageType attribute values specified earlier. Once again, hats off to Joel! This part right here got me excited! Nice clean code that just works - it sure gives you a sense of accomplishment!

Adding page properties using Page Type Builder

Our page type won’t do much good without any page properties. First off, let’s create a well-known MainBody property!

I added an XHTML property using Erik Nordin’s nifty little snippet:

Adding a page type property using PageTypeBuilder

Notice how the LongStringSettings parameter can be used to specify which toolbar options should be available:

using EPiServer.Core;
using PageTypeBuilder;
using EPiServer.SpecializedProperties;
using EPiServer.DataAbstraction;
using EPiServer.Editor;
 
namespace TedNyberg
{
   [PageType(
      Name="My Page Type",
      Description="Page type created using PageTypeBuilder attributes",
      Filename="/Templates/PageTypeBuilder/MyPageTemplate.aspx")]
   public class MyPageType : TypedPageData
   {
      [PageTypeProperty(
         EditCaption="Main body",
         HelpText="The main rich text content of the page.",
         DefaultValue="<p>Nothing to see here</p>",
         DefaultValueType=DefaultValueType.Value,
         DisplayInEditMode=true,
         Required=true,
         Searchable=true,
         SortOrder=100,
         UniqueValuePerLanguage=true,
         Type=typeof(PropertyXhtmlString),
         LongStringSettings=(
            EditorToolOption.DynamicContent ^
            EditorToolOption.ToggleHtml ^
            EditorToolOption.InsertImage ^
            EditorToolOption.InsertUrl))]
      public virtual string MainBody
      {
         get;
         set;
      }
   }
}

After having compiled the application I could now see the following in EPiServer admin mode:

Page type property settings in EPiServer admin mode

Note: you can use the EditorToolOption.All enum to specify toolbar options for the XHTML editor. The following would enable all options except for the Font option (this is currently the default when using Erik Nordin’s code snippet):

LongStringSettings= ( EditorToolOption.All ^ EditorToolOption.Font)

Accessing the property value

First I created a new page based on My Page Type:

Creating a new page in EPiServer

My new page got page ID 26:

Page meta data in EPiServer edit mode

Under normal circumstances I would get the MainBody property value using syntax similar to this:

string content = CurrentPage["MainBody"];

Easy enough, for sure, but since it isn’t strongly typed you won’t be able to trap errors until run-time. For example if the MainBody property doesn’t exist for the current page.

Using PageTypeBuilder we can use the following syntax instead:

string content = CurrentPage.MainBody

Here’s another example, in this case to retrieve the MainBody property value of the newly created page with page ID 26:

string content = DataFactory.Instance.GetPage<MyPageType>(new PageReference(26)).MainBody;

Creating an inheriting page type

I created another page type called My Other Page Type. This one also has a MainBody property since I inherited from My Page Type:

[PageType(
    Name="My Other Page Type",
    Description="Another page type created using PageTypeBuilder attributes",
    Filename="/Templates/PageTypeBuilder/MyPageTemplate.aspx")]
public class MyOtherPageType : MyPageType
{
 
}

Now, after re-compiling I could see two page types in EPiServer:

EPiServer page type list

Looking at the settings for My Other Page Type I could see that this page indeed also has a MainBody property:

Page properties of the inheriting page type

Modifying a property value programmatically

I changed my page template logic to update the MainBody property each time the page loads:

public partial class MyPageTemplate : TemplatePage<MyPageType>
{
   protected override void OnLoad(System.EventArgs e){base.OnLoad(e);
   {
      // Create a writable copy
      MyPageType copy = CurrentPage.CreateWritableClone();
 
      // Set the MainBody property value
      copy.MainBody = string.Format("<p>Page last loaded: {0}</p>", DateTime.Now);
 
      // Publish the modified page
      DataFactory.Instance.Save(copy, SaveAction.ForceCurrentVersion);
   }
}

Now, after having refreshed the page, I see the following:

Page rendered after programmatically changing a page property value 

Lastly, I would once again like to thank Joel for his work on the Page Type Builder project – truly awesome!