EPiServer  /  CMS August 25, 2009

Developing with Page Type Builder – Inheritance and Specifying Property Types

In this part of the tutorial we’ll take a look at inheritance between page types and how we can explicitly specify which type an EPiServer property should be of.

What we learned in the previous part

In the previous part of the tutorial you where introduced to the example project, Bananas, and we created a first page type by inheriting from TypedPageData and adding the PageType attribute to the class. We also added a property to the page type by creating a regular code property to which we added a PageTypeProperty attribute. Finally we created an ASPX page that rendered the MainBody property, accessing it in a strongly typed way.

Adding the BasePageData and EditorialPage base classes

Just like the article page type the start page should have a MainBody property. We could of course create a class for the start page page type and add the property to it, but we would then be duplicating the exact same code in both the ArticlePage class and the class for the start page page type. Instead we’ll create an abstract base class, EditorialPage, that both will inherit from.

While we’re at it we’ll also create a base type that all of our page types should inherit from, BasePageData. Doing so will make it very easy for us to add properties or functionality to all of our page types should the need arise (it will later on in the tutorial).

Let us begin by creating the BasePageData class. It should be abstract and inherit from TypedPageData. As it won’t represent an actual page type it doesn’t need to have a PageType attribute. Here’s how it should look:

using PageTypeBuilder;

namespace Bananas.PageTypes
{
    public abstract class BasePageData : TypedPageData
    {
    }
}

Next we create another new class, EditorialPage, that inherits from BasePageData. It to should be abstract.

namespace Bananas.PageTypes
{
    public abstract class EditorialPage : BasePageData
    {
    }
}

With that done it’s time to move the MainBody property from the ArticlePage class to EditorialPage. Simply cut the code from ArticlePage and paste it into EditorialPage. Finally modify ArticlePage so that it inherits from EditorialPage instead of TypedPageData.

The EditorialPage class should now look like this:

using PageTypeBuilder;

namespace Bananas.PageTypes
{
    public abstract class EditorialPage : BasePageData
    {
        [PageTypeProperty]
        public virtual string MainBody { get; set; }
    }
}

And the ArticlePage class should look like this:

using PageTypeBuilder;

namespace Bananas.PageTypes
{
    [PageType(Filename = "~/Templates/Pages/Article.aspx")]
    public class ArticlePage : EditorialPage 
    {
    }
}

Adding a MainBody property to the start page using inheritance

So far we really haven’t modified or added any page types. We have however set it up so that creating a page type for the start page with a MainBody property will be a breeze. Add a new class named StartPage that inherits from EditorialPage and has a PageType attribute with the Filename property set to the path of the Start.aspx file.

Please note that the name of the class is important here. As we saw in the previous part the Bananas site already has a page type named StartPage. The default behavior in Page Type Builder is to use the name of the page type as the key by which page types in the EPiServer database and in the code are matched. There is more to this, but for now, please just make sure that the class’ name matches that of the existing page type exactly.

Here’s how the StartPage class should look:

using PageTypeBuilder;

namespace Bananas.PageTypes
{
    [PageType(Filename = "~/Templates/Pages/Start.aspx")]
    public class StartPage : EditorialPage
    {
    }
}

Just like for articles we have to add some code to render the contents of the MainBody property. Open up the code behind file for Start.aspx and make it inherit from TemplatePage<StartPage>. It should now look like the code below.

using System;
using PageTypeBuilder.UI;
using Bananas.PageTypes;

namespace Bananas.Templates.Pages
{
    public partial class Start : TemplatePage<StartPage>
    {
        protected void Page_Load(object sender, EventArgs e) {}
    }
}

Finally make Start.aspx display the MainBody property.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Start.aspx.cs" Inherits="Bananas.Templates.Pages.Start" MasterPageFile="~/Templates/MasterPages/Main.Master" %>
<asp:Content ContentPlaceHolderID="ContentPlaceHolderMainContent" runat="server">
    <%= CurrentPage.MainBody %>
</asp:Content>

Compile and go to edit mode and you’ll see that the start page now has a Main Body property. Add some content to it and you’ll see that it gets rendered when viewing the page.

StartPageWithMainBody

Adding a Headline Property

Both the article and start page could do with a headline. Luckily adding one is quite easy as both page types inherit from the same base class, EditorialPage. Compared to the MainBody property one thing is different though, the Headline property should not be an XHTML string property but a short string property. As XHTML string is the default property type that Page Type Builder maps code properties of type string to we’ll have to explicitly tell it that the property should be of type PropertyString. This is done by setting the Type property of the PageTypeProperty attribute to the type that the property should be of, in this case PropertyString.

So, to add a Headline property of type PropertyString to both the start page and article page types you should add a new code property to the EditorialPage class named Headline. It should be public and virtual, of type string and have a PageTypeProperty attribute. The PageTypeProperty attribute’s Type property should be set to typeof(PropertyString). When done the EditorialPage class should look like this:

using EPiServer.Core;
using PageTypeBuilder;

namespace Bananas.PageTypes
{
    public abstract class EditorialPage : BasePageData
    {
        [PageTypeProperty(Type = typeof(PropertyString))]
        public virtual string Headline { get; set; }

        [PageTypeProperty]
        public virtual string MainBody { get; set; }
    }
}

Compile the project and edit the start page or article and you’ll see the Headline property there.

Headline

Specifying the sort order for properties

Unfortunately the Headline property is placed after the MainBody property as it was created later. That isn’t very logical as the headline will be rendered above the body content. To fix this we can explicitly tell Page Type Builder what sort order the two properties should have by specifying the SortOrder property of each PageTypeProperty attribute.

public abstract class EditorialPage : BasePageData
{
    [PageTypeProperty(Type = typeof(PropertyString), SortOrder = 0)]
    public virtual string Headline { get; set; }

    [PageTypeProperty(SortOrder = 1)]
    public virtual string MainBody { get; set; }
}

Rendering the Headline Property

Finally we should make the Start.aspx and Article.aspx page templates render the Headline property. To do that we add the below markup to them, before the part that renders the MainBody property.

<h1><%= CurrentPage.Headline %></h1>

Try it out by entering a headline for the start page. Leave the article’s headline empty for now.

StartPageHeadline

Recapitulation and conclusion

Part2UMLDiagramIn this part of the tutorial we created two abstract classes, one for all of our page types and one with common properties for editorial pages. We saw how inheritance works between page types when both the start page and article page types inherited their properties from the EditorialPage class.  We also saw how to explicitly specify the type and sort order for a property.

As our page types are classes now, and as we have created polymorphic relationships between them we can start thinking about page types in more object oriented terms than before. One such example is that we can illustrate the relationships between them using UML class diagrams, like the one to the right here.

In the next part we’ll take a look at a different way to implement property access instead of automatic properties and how that enables us to use conditional logic when accessing property values in our page types. 

Parts in this tutorial

  1. Gettings started
  2. Inheritance and Specifying Property Types
  3. Advanced Property Access
  4. Using Interfaces and Advanced Inheritance
  5. Source code

    You can download the source code, both the starting point and the finished site, here.

PS. For updates about new posts, sites I find useful and the occasional rant you can follow me on Twitter. You are also most welcome to subscribe to the RSS-feed.

Joel Abrahamsson

Joel Abrahamsson

I'm a passionate web developer and systems architect living in Stockholm, Sweden. I work as CTO for a large media site and enjoy developing with all technologies, especially .NET, Node.js, and ElasticSearch. Read more

Comments

comments powered by Disqus

My book

Want a structured way to learn EPiServer 7 development? Check out my book on Leanpub!

More about EPiServer CMS