Developing with Page Type Builder – Getting Started

In this tutorial I’ll demonstrate how to build a simple but fully functional site using EPiServer CMS and Page Type Builder. In doing so I’ll show basic usage of Page Type Builder as well as some advanced usages.

The example project

To illustrate how to work with Page Type Builder we’ll construct a simple example site called Bananas. You don’t need to actually write the code that I do if you don’t want to and can instead print this tutorial and read it in the tub while taking a bath, or you can apply the parts you need to a project of your own.

If you however do wish to write the code and build the example site yourself you can download the source code package. In it you’ll find two projects. One is the finished site and one is the starting point from which this tutorial begins. Included with the source code is instructions for setting up the projects.

The Bananas site will have three page types and three page templates (ASPX files). All of the page templates uses the same master page and the master page in turn uses two user controls, one for for rendering meta data and one for the sites menu.

The starting point

Visual Studio Solution Explorer at the starting pointThis tutorial takes of from a point where we have the master page, all of the ASPX files and all of the user controls with most of the HTML markup in them but a lot of logic missing. We also have a start page and it’s page type as adding a start page to an empty EPiServer site is a bit tricky. We also have a couple of extension methods for the string class which will come in handy during the construction of the site.

To the right you can see how the project looks in Visual Studios solution explorer. Below you can see how the list of page types from admin mode and the page tree in edit mode looks.

Page Types at the Starting Point 

The Page Tree at the Starting Point

Referencing Page Type Builder

The very first thing we must do is reference the PageTypeBuilder.dll assembly. That will in turn require that our web application has access to two assemblies from the Castle project, Castle.Core.dll and Castle.DynamicProxy2.dll. All of these are included when you download Page Type Builder from the project site at CodePlex. They are also included in the source code package.

So, locate these three files and copy them to your bin directory. Then add a reference to the PageTypeBuilder.dll assembly to your project.

Creating the article page type

With the refence to Page Type Builder added we are ready to create our first page type that is defined in code, a page type for articles. It should contain a string property called Headline for the article’s headline and a XHtml string property named MainBody for the article’s content. To get started we begin by creating the page type with only the MainBody property. ArticlePageInSolutionExplorerWe do this by creating a new class. You can place it anywhere in your project but I recommend grouping page types in a folder, so begin by adding a new folder to the project named PageTypes. Then we create a new class in that folder named ArticlePage. 

Turning the ArticlePage class into a page type requires us to do two things. We must make it inherit from the TypedPageData base class in Page Type Builder and we must add a PageType attribute to it.

using PageTypeBuilder;

namespace Bananas.PageTypes
{
    [PageType]
    public class ArticlePage : TypedPageData 
    {
    }
}

Next we must specify that the page type should be rendered by the Article.aspx page template. We do this by specifying the Filename property of the PageType attribute.

using PageTypeBuilder;

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

Finally we add the MainBody property to it by adding a new public and virtual string property called MainBody to the class. We implement it as an automatic property, that is we let the compiler generate the get and set implementations for us by just writing “get; set;”. To tell Page Type Builder that this code property is an EPiServer property we add a PageTypeProperty attribute to it.

using PageTypeBuilder;

namespace Bananas.PageTypes
{
    [PageType(Filename = "~/Templates/Pages/Article.aspx")]
    public class ArticlePage : TypedPageData 
    {
        [PageTypeProperty]
        public virtual string MainBody { get; set; }
    }
}

Our article page type is now complete in it’s first version, but we must also implement some logic for displaying it’s content in the Article.aspx file. Begin by opening up it’s code behind file. It looks like the code below.

using System;
using System.Web.UI;

namespace Bananas.Templates.Pages
{
    public partial class Article : Page
    {
        protected void Page_Load(object sender, EventArgs e) {}
    }
}

As you can see it currently inherits from System.Web.UI.Page. To turn it into an EPiServer page template we would normally make it inherit from EPiServer.TemplatePage or EPiServer.EditPage but that would mean that it’s CurrentPage property would be of type PageData. If we instead make it inherit from PageTypeBuilder.UI.TemplatePage<ArticlePage> the CurrentPage property will be of type ArticlePage. Let’s do that.

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

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

Next, open up the markup (or code in front) part of Article.ASPX. It looks like this:

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

Notice that it already uses the master page and that it already has a Content control with the ContentPlaceHolderID attribute set to the main content area in the master page. To render the MainBody property place the caret in between <asp:Content> and </asp:Content> and write <%= CurrentPage.MainBody %>. Article.aspx should now look like this:

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

We are now done creating the article page type in a first version and we’ve also made sure that the MainBody property will be rendered. Try it out by creating a new page of type Article under the start page. An article about the history of bananas perhaps?

CreateNewPageArticle2

When the page is saved and published it will render the MainBody property in the content area of the page. You’ll also see the name of the page in the menu as the menu renders the start page’s children.

Article1

A quick recapitulation

In this part of the tutorial you’ve been introduced to the example project. We have also created a first page type by inheriting from TypedPageData and adding the PageType attribute to the class. We have 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.

In the next part we’ll add a MainBody property to the start page too, as well as a headline property to both the article and start page page types. In the process we’ll learn about basic inheritance between page types and how to create a property of a different type than XHTML string.

Parts in this tutorial

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

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.

Comments

  1. Jonathan Pettersson's avatar

    Jonathan Pettersson 2 years ago

    Imponerande! Bra jobbat med PTB och bra blogget!

  2. Øyvind Hognestad's avatar

    Øyvind Hognestad 1 years ago

    When using the PTB 1.1 for EPiServer CMS5 the Name-property have to be set. If not, the pagetype will not appear in EPiServer Admin Mode.

    [PageType(Filename = "~/Templates/Pages/Article.aspx", Name="Article")]
        public class ArticlePage : TypedPageData
        {
            [PageTypeProperty]public virtual string MainBody { get; set; }
        }
    


    But yes, PTB is cool !
  3. Joel Abrahamsson's avatar

    Joel Abrahamsson 1 years ago

    Øyvind, that shouldn't be the case, it should create a page type with the name of the class. What happens for you if you don't specify it?

  4. Øyvind Hognestad's avatar

    Øyvind Hognestad 1 years ago

    Nothing happend, no new pagetypes in Admin mode if I did not specify it. Tried several times and the only thing I did was to add Name property and the pagetype appeared as expected in Admin mode. This was on a default EPiServer CMS5 R2 installation. Tried once more with a new pagetype (new class) without a Name property and it worked like you say.

    Will install a new examplesite and test once more. Probably user finger trouble.

    Using PTB dll version 1.1.0.0.

  5. Tom's avatar

    Tom 1 years ago

    I experienced an error after installing PTB demo files. Solved thanks to http://world.episerver.com/Blogs/Marthin-Freij/Dates/2010/4/EPiServer---ReflectionTypeLoadException-Unable-to-load-one-or-more-of-the-requested-types/

    Thought I should share here too!

  6. Andreas's avatar

    Andreas 1 years ago

    I'm getting this error, any idéas?

    System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. The following information may be a subset of the Type/LoaderException information present - inspect with debugger for complete view.
    Check assemblies [] and/or types []. Information from LoaderExceptions property [Could not load file or assembly 'PageTypeBuilder, Version=1.3.0.0, Culture=neutral, PublicKeyToken=6fb8762af0e6dbed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)].


    Source File: c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\b7c8d52a\c3e89fc7\App_global.asax.wsals6xw.0.cs Line: 0

  7. Kenia's avatar

    Kenia 1 years ago

    I had the same problem while loading some assemblies as well and the solution was to add them to the GAC, maybe not the best solution in all cases scenarios but it works. Hope it helps!

  8. Veerle's avatar

    Veerle 7 months ago

    How do create that installation package for the bananas site? I would like to create something like that myself.

Follow me on Twitter

  1. @tim_abell The gigantic ones are for customers who specifically ask for them only :) 1 months ago
  2. Looking to buy a gigantic easter egg filled with candy for delivery in Stockholm. Any recommendations? 1 months ago
  3. @strandberg_m Du måste skriva om resultatet efteråt! 1 months ago
follow me

Latest comments

  1. Joel Abrahamsson wrote "Hi Jonas! The fluent API is really geared towards working..." on Building a search page for an EPiServer site using Truffler
  2. Jonas wrote "Thank you for one more great write up! If you're not lucky ..." on Building a search page for an EPiServer site using Truffler
  3. David Knipe wrote "The CategoriesFacet method will save me a load of headaches ..." on Cool new features in the Truffler .NET API

About this site

This blog is built with EPiServer Community, EPiServer CMS, ASP.NET MVC and a bunch of other great products. The source code is available for download at the projects page, where you also can read more about this site and my other projects.

read more