New EPiServer website using Template Foundation

In this post we'll look at how to set up an EPiServer CMS 6 website from scratch based on EPiServer Template Foundation.

  • 16 July 2010
  • 0

Install EPiServer CMS 6

First of all we install a new EPiServer website using Deployment Manager:

EPiServer Deployment Manager

We refrain from installing the Public Templates package, so after install this is our fancy start page:

Placeholder start page after EPiServer install

The core install contains the following files (including default.htm which is the aforementioned fancy start page, but if you’re like me you’ll instantly delete it):

Core install files

Set up the website project in Visual Studio

Create a project file for the EPiServer website

Next I want a Visual Studio solution for the project, so I create a new ASP.NET project in Visual Studio:

Creating a new Visual Studio project for the EPiServer website

I only do this to quickly get my hands on a Visual Studio project file and assembly information file (AssemblyInfo.cs located in the Properties folder) to use for my EPiServer website (I delete the rest of the default files that come with setting up a new Web Application project):

Added Visual Studio project file for EPiServer website

Next we open up the new project file and remove the Default.aspx reference (since the file no longer exists in the project) and also the Scripts folder:

Removing standard file references from project

After deleting those we can toggle Show All Files to include the files that came with the EPiServer install:

Including EPiServer files in Visual Studio project

Managing different build configurations

This doesn’t have anything to do with EPiServer Template Foundation, but I still think it’s important for EPiServer projects. We set up a separate [Configuration] folder with sub folders named according to the different build types in Visual Studio and then set up a pre-build event to copy files from the associated configuration folder to the root when compiling:

 Using build-specific folders for configuration files

Pre-build event in Visual Studio

In ASP.NET 4 Visual Studio 2010 a new way of managing build-specific configuration files was introduced, but we’ll stick with our old proven way of accomplishing it this time. :)

Update: I just published a post explaining how config transforms can be used in Visual Studio 2010 to manage build-specific configurations, including EPiServer settings.

Add third-party assemblies

We put all third-party assemblies for EPiServer websites in a folder called [Library]. If you looked closely at the pre-build event above you noticed we copy these binaries to the bin folder before building:

Third-party assemblies in separate folder

Add MSBuild files

This isn’t required for EPiServer Template Foundation, but we put our MSBuild files in a folder called [MSBuild]. In it we put MSBuild configuration files and other resources such as libraries and executables required by the MSBuild scripts (for things such as minifying CSS and JavaScript files):

MSBuild folder and files

Add references to third-party assemblies

Next we’ll add references to required third-party assemblies, such as Page Type Builder. Note that we reference these assemblies from the [Library] folder:


Note though that we set Copy Local to false since we copy all our third-party assemblies through the pre-build event defined earlier:


We add references to the following assemblies:

  1. EPiServer Template Foundation (ETF)
  2. Page Type Builder (here’s an introduction to Page Type Builder)
  3. Castle.Core (required by PTB)
  4. Castle.DynamicProxy2 (required by PTB)
  5. EPiServer
  6. EPiServer.BaseLibrary
  7. EPiServer.Framework
  8. EPiServer.UI
  9. EPiServer.Web.WebControls
  10. System.ComponentModel.Composition (required by EPiServer.Framework)
  11. dotless.Core (if used for CSS parsing)

Add Template Foundation configuration elements

First we’ll add the DynamicImageProcessor section group to the <configSections> element:

<section name="DynamicImageProcessor" type="TemplateFoundation.Handlers.DynamicImageProcessor.ProcessorConfig" />

Next we’ll add the tag prefix for Template Foundation controls to the <controls> element:

<add tagPrefix="ETF" namespace="TemplateFoundation.WebControls" assembly="TemplateFoundation"/>

Next we’ll add some HTTP handlers that come with Template Foundation to the <handlers> element:

<add name="MetaWeblog" type="TemplateFoundation.MetaWeblog.MetaWeblogHandler" path="/metaweblog" verb="*" />
<add name="LiveWriterManifest" type="TemplateFoundation.MetaWeblog.ManifestHandler" path="/wlwmanifest.xml" verb="*" />
<add name="ReallySimpleDiscovery" type="TemplateFoundation.MetaWeblog.ReallySimpleDiscoveryHandler" path="/rsd.xml" verb="*" />
<add name="TemplateFoundationImagesLoader" type="TemplateFoundation.Handlers.EmbeddedImagesHandler" path="/TemplateFoundation/images/*" verb="GET"/>
<add name="TemplateFoundationHtmlLoader" type="TemplateFoundation.Handlers.EmbeddedHtmlHandler" path="/TemplateFoundation/*.html" verb="GET" />
<add name="PermanentLinksHandler" type="TemplateFoundation.Handlers.PermanentLinksHandler" path="/link/*" verb="*" />

Make sure you add these after any <clear/> element you might have in there!

We use the CSS parser in ETF (which utilizes dotLess) and we want a HTTP handler to manage CSS parsing while in development, but the pre-parsed minified CSS files when in production. So, we use these handlers for the Stylesheets folder where we keep all of our CSS files:

<location path="Templates/Stylesheets">
<!-- CSS parser used in development environment, production environment uses pre-parsed minified CSS files -->
<add name="CssParserProd" verb="GET,HEAD" path="*.min.css" type="EPiServer.Web.StaticFileHandler, EPiServer"/>
<add name="CssParserDev" verb="GET,HEAD" path="*.css" type="TemplateFoundation.Handlers.Css.CssParserHandler" />
<!-- End CSS parsed -->

The MasterPageBase renders different stylesheet and JavaScript links depending on the debug attribute in web.config:


When debug is set to true the non-minified versions are linked.

We want to use the DynamicImageProcessor for site graphics, so we add the handler for common graphics types:

<location path="Templates/Stylesheets/gfx">
<!-- Dynamic Image Processor -->
<add name="png" verb="GET,HEAD" path="*.png" type="TemplateFoundation.Handlers.DynamicImageProcessor.Processor" />
<add name="jpg" verb="GET,HEAD" path="*.jpg" type="TemplateFoundation.Handlers.DynamicImageProcessor.Processor" />
<add name="gif" verb="GET,HEAD" path="*.gif" type="TemplateFoundation.Handlers.DynamicImageProcessor.Processor" />
<!-- End of Dynamic Image Processor-->

Note: you could obviously add these handlers for other locations or paths, too. For example, you could add them to the “PageFiles” and “Global” locations to enable DynamicImageProcessor for images uploaded to the VPP.

Since DynamicImageProcessor used a file-based cache we need to specify which folder to use for the cache in web.config (note that we added the configuration section earlier):

<Cache CacheDirectory="C:\Temp\dynamicimageprocessor-test" Enabled="true" />

Create an EPiServer folder structure

We use a folder structure similar to that of the Public Templates package:


Setting the root as the start page

Because we didn’t install the Public Templates project we don’t have any content on our new EPiServer site. So, in order to be able to login we need to set the root page as the site’s start page inside episerver.config:

Setting the root as the start page in episerver.config

Oh, and while you’re in there, go ahead and change the display name so it doesn’t say PublicTemplates:

siteDisplayName setting in episerver.config

And finally, please replace the description so it doesn’t read “Example Site”! :)

Setting site description in episerver.config 

Adjust the file paths for system page types

For some reason the file paths for the SysRoot and SysRecycleBin page types are incorrect after installing EPiServer. I manually edit these to include the /cms part of the path:


Adding master pages

All our master pages should inherit from MasterPageBase. So, we’ll create our master pages in the MasterPages folder…


…and make them inherit from MasterPageBase:

public partial class TwoColumns : MasterPageBase

Setting up basic EPiServer page types

If we go to admin mode we’ll see we only have the two basic system page types:


Next we’ll add Start Page and Standard Page page types using the Template Foundation base classes.

Create a base class for your templates

Before you start creating template pages you should create your own base class inheriting from TemplatePageBase and have your templates inherit that base class:

public class HemsoTemplatePage<T> : TemplatePageBase<T> where T : PageTypeBase

Note that the generic class has been fitted with a type constraint meaning the page templates need to be created for a page type class which derives from the PageTypeBase class in ETF.

Create the page type for the start page

We’ll create a new class called StartPage.cs:


We’ll make this class inherit the StartPageBase class, which is part of ETF:

public class StartPage : StartPageBase

If we reload admin mode we’ll see our new page type has appeared:


If we edit the StartPage page type we can see a number of page properties, including those used to specify the site settings required by ETF, such as these for specifying the page types used for person and RSS pages:


However, to have the page type map to the correct page template we’ll specify the Filename parameter of the PageType attribute:

[PageType(Filename = "/Templates/TemplatePages/StartPageTemplate.aspx")]
public class StartPage : StartPageBase

Next we’ll create a template page for the start page under the TemplatePages folder…


…and make it inherit from TemplatePageBase (or, preferably, the custom base class created for the project):

public partial class StartPageTemplate : TemplatePageBase<StartPage>

Note: we use the naming pattern PageTypeNameTemplate to avoid class name clashes between page types and their corresponding page templates.

Create the page type for standard pages

For the Standard Page page type we first create the page type definition under PageTypes

Standard page type definition class

…and we make it inherit from StandardPageBase (note that we’ve specified a few more parameters for the PageType attribute to make the page type appear nicer in edit mode):

Name = "Standard page",
Description = "Standard page template for editorial content",
Filename = "/Templates/TemplatePages/StandardPageTemplate.aspx")]
public class StandardPage : StandardPageBase

Next we’ll create its template page file under TemplatePages

Page template for the StandardPage page type

…and once again make the template inherit from TemplatePageBase, but this time for the StandardPage page type:

public partial class StandardPageTemplate : TemplatePageBase<StandardPage>

If we log in to admin mode we can see our StandardPage page type has a number of familiar page properties, such as Main body:


Configure language settings

Before creating any content, make sure you configure the language settings for the website:

Setting Language Settings for EPiServer site

Create start page

Create a start page under the root page:


Once you’ve published the start page make sure you set the pageStartId attribute in episerver.config to its page ID:


You’ll find the Page ID of the start page by hovering over it in the content tree:


Next we should specify some site settings by going to the Site settings tab of the start page, but before we do we need to create some additional page types.

Create page types for news

When publishing articles under the news container the pages are sorted into date folders. So, to create a news listing page we need the following page types:

  1. News container (our “News” page)
  2. Date listing (acts as date folders and also for listing articles for a given year or month)
  3. Tag listing (used for creating tag pages and also to list articles with a specific tag)
  4. Article
  5. RSS feed

We’ll create our page types and template much in the same way as we did before.

News container

The “News” page will be based on a page type called NewsListPage which in turn inherits ArticleContainerBase (the base class in ETF):

Name="News list",
Description = "Used to list the most recent news articles",
Filename = "/Templates/TemplatePages/NewsListPageTemplate.aspx")]
public class NewsListPage : ArticleContainerBase


Date listing

The page type used for date folders will be called ArticleDateListing and inherit the ETF base class ArticleDateListingBase:

Name="Date listing",
Description="Used to view a list of articles published in a specific year or month",
Filename = "/Templates/TemplatePages/ArticleDateListingTemplate.aspx")]
public class ArticleDateListing : ArticleDateListingBase


Tag listing

Name="Tag listing",
Description="Used to view a list of articles with a specific tag",
Filename = "/Templates/TemplatePages/ArticleTagListingTemplate.aspx")]
public class ArticleTagListing : ArticleTagListingBase


The Article page type should inherit the ETF base class ArticleBase:

Description = "Used to publish news articles",
Filename = "/Templates/TemplatePages/ArticlePageTemplate.aspx")]
public class ArticlePage : ArticleBase


RSS feed

We need a page type for RSS feeds, and we’ll create one called RssFeedPage inheriting RssPageBase:

Name="RSS feed",
Description = "Used to publish an RSS feed",
Filename = "/Templates/TemplatePages/RssFeedPageTemplate.aspx")]
public class RssFeedPage : RssPageBase

When we create the template page for the RSS page type we inherit the TemplateRssPageBase class:

public partial class RssFeedPageTemplate : TemplateRssPageBase { }

No markup is required in the code-front file, and no additional logic is required for an RSS feed listing articles.

Create a person page type

For features such as the Contact person property we need a page type for creating persons and specifying data such as name, e-mail address, phone number, etc.

We’ll create a page type called PersonPage and make it inherit PersonPageBase:

Name = "Person",
Description = "Used to store data about a contact person")]
public class PersonPage : PersonPageBase

We don’t specify the Filename parameter in this case since our person page won’t have any presentation – it’s simply used as a data container for person details.

Create the news container page

Using our NewsListPage page type we created earlier we’ll create a new page on the site (so we’ll have a page to specify as the news container among the site settings later).

Create the tags container page

We don’t have to use any specific page type for the tags container page, but we have to create a page under which all tag pages should be created.

Specify site settings

Now that we’ve created the page types and container pages we need we’ll specify some ETF settings through the Site settings tab by editing the start page:

Specifying ETF settings for the website

Create some news articles

To create an article, simply right-click the news container page and create a new page of type Article:

Creating a new article under the news container

When the new article page is created (or later published) it will be put in a date folder based on year and month (it looks at the StartPublish property):

New article under an automatically generated date folder

Let’s create some additional articles for our upcoming news list:


Create a news list page

Now we can create a template for our NewsListPage page type. The template should list the most recent articles.

We’ll create a template called NewsListPageTemplate.aspx and insert a simple NewsList control:

<EPiServer:NewsList ID="news" runat="server"> 
<HeaderTemplate><div id="news-list"></HeaderTemplate>

<div class="first">
<ETF:Property ID="Property1" PropertyName="PageStartPublish" DateFormat="d MMMM yyyy" ContainerElement="p" ContainerCssClass="date" runat="server" />
<ETF:Property ContainerElement="h2" PropertyName="Title" runat="server" />
<ETF:Property ContainerElement="p" ContainerCssClass="intro" PropertyName="Title" runat="server" />

<ETF:Property PropertyName="PageStartPublish" DateFormat="d MMMM yyyy" ContainerElement="p" ContainerCssClass="date" runat="server" />
<ETF:Property ContainerElement="h2" PropertyName="Title" runat="server" />
<ETF:Property ContainerElement="p" ContainerCssClass="intro" PropertyName="Title" runat="server" />


Note that we use the ETF version of the Property control which allows us to set which container element to use (instead of the standard <span>) and also to set the date format for DateTime-based properties.

In the code-behind file of our template we’ll simply bind the NewsList control to the 20 most recent articles by using the PageFactory class:

public partial class NewsListPageTemplate : TemplatePageBase<NewsListPage>
protected override void OnLoad(EventArgs e)

news.DataSource = PageFactory.Instance.GetArticles(20);

And that’s our basic news listing:

News list template

If we create a page on our site using the RSS feed page type we created earlier we’ll also have an RSS feed available.

I added some tags to one of the articles…

Editing EPiServer tags using EPiServer Template Foundation

…and these are also included in the RSS feed:

RSS feed for articles using EPiServer Template Foundation

Further reading

For an example where we add EPiServer Template Foundation to an existing website, see Introduction to EPiServer Template Foundation (which also covers how to publish posts and pages to your EPiServer site using Live Writer through the MetaWeblog API).

Upcoming blog posts

I’m working on a series of blog posts aimed at explaining additional features in EPiServer Template Foundation, such as:

  • Publishing articles and pages using Windows Live Writer through the MetaWeblog API (there’s information
  • Creating tag and date listings for articles
  • Working with page tags
  • Making use of the ETF Property control
  • Overview of the PageFactory and Settings classes as well as available extension methods
  • Using additional item templates with the ETF PageList control
  • Creating rich UI custom properties using the UserControlPropertyBase class
  • In-depth look at the MasterPageBase class
  • Image resizing and cropping using DynamicImageProcessor
  • Setting default page property values based on business logic (as opposed to constant default values set in page type definitions)
  • Customizing RSS feeds

Feedback is much appreciated!

Feel free to post comments below or for any feedback or questions you might have!