A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

Mikael Nordberg
May 11, 2009
  5131
(0 votes)

Strongly typed property access- Part two

As promised by Daniel in part one, here is part two!

In this post I’ll try to explain how we could automatically deploy our mapped properties that we use to get strongly typed properties (see Daniels post) in our templates by using some reflection, conventions and attributes.

Creating a new Template

First we create a new Web Form/Page Template in Visual Studio and change the inheritance from EPiServer.TemplatePage to our own extended class TemplatePage<T>. 

To add properties we create a class-file for the properties that we will use in our template. Neither the PageType or associated properties has to be present in EPiServer.

   1: public class MyPageProperties : PropertiesBase
   2: {        
   3:     public PropertyString Heading { get; set; }
   4:     public PropertyXhtmlString MainBody { get; set; }        
   5:     public PropertyUrl SomeUrl { get; set; }
   6: }

PageTypeBuilder

PageTypeBuilder is the tool responsible for creating and updating  PageTypes and properties in EPiServer.

To execute it, we need to add some code when the application starts, for instance in a PlugIn or in Global.asax.

   1: public class PageTypeDefPlugin : EPiServer.PlugIn.PlugInAttribute
   2: {
   3:     public static void Start()
   4:     {
   5:         var builder = new PageTypeBuilder<PropertiesBase>(Assembly.GetExecutingAssembly().FullName)
   6:                           {
   7:                                   Settings = new PageTypeBuilderSettings {TabName = "Information", VirtualPathRoot = @"\Pages\"}
   8:                           };
   9:  
  10:         builder.UpdatePageTypes();
  11:     }
  12: }

PropertiesBase is added as a generic type and the BuildPageTypes method takes a params string[] with names of assemblies to scan for mapping classes.

The tool will look for classes that are subclasses of T (= PropertiesBase) and build PageTypes out of these. Each class will become a PageType and each property will be added as a  EPiServer property.

For global default settings a PageTypeBuilderSettings object is used. Here it’s possible to add virtual path, default tab, if unmapped properties should be deleted  or not and if existing properties should be updated.

Attributes

But what about Help texts,  Tabs and Descriptions? The tool will guess/use conventions for these. The class name - “Properties” will be the name for the PageType (class “StartProperties” = PageType “Start”), if no Tab name is specified, the property will be added to the “Information” tab (if not overridden by the global settings) and so forth.

To override this and to add additional information we could decorate our mapping classes with attributes.  Attributes could be Name of the page/property, Edit Heading, Tab, Default value, Language specific and some others. Pretty much the same as we have in Admin mode.

If we have properties that are shared between templates these could be added to either the PropertiesBase class or to another class that inherits PropertiesBase and then use this class as subclass for our mappings.  Since we don’t want this class to be a PageType there is a [Ignore] attribute that could come in handy.

The sort order of the properties will be the same as the order in our mapping classes.

Screenshots

some pictures might say more  than 1000 words…

 1.pagetypes
Before

For mapping class we use this:

   1: public class MyPageProperties : PropertiesBase
   2: {
   3:     [HelpText("Ingress")]        
   4:     public PropertyString MainIntro { get; set; }
   5:     [HelpText("Primär text")]        
   6:     public PropertyXhtmlString MainBody { get; set; }
   7:     [HelpText("Länk till bild")]        
   8:     public PropertyImageUrl ImageUrl { get; set; }
   9: }

This will result in this new PageType:  
2.mypage   Sort order of properties will be the same as in the mapping class

Code is king!

Since we add, update and delete properties when the application starts we will not depend on a specific database. This could be useful in a continuous integration scenario where the development database differs from the database used for test and of course if all developers in a team have their own (local) database.

Summary

This tool is pretty much a “proof of concept” that could be used to complement our way to handle strongly typed properties. It' can not (yet) handle all features of PageTypes that exists in EPiServer (dynamic properties to mention one) but will ease the pain of creating PageTypes and  adding properties ;)

So, what do you think?

May 11, 2009

Comments

Please login to comment.
Latest blogs
Looking back at Optimizely in 2025

Explore Optimizely's architectural shift in 2025, which removed coordination cost through a unified execution loop. Learn how agentic Opal AI and...

Andy Blyth | Dec 17, 2025 |

Cleaning Up Content Graph Webhooks in PaaS CMS: Scheduled Job

The Problem Bit of a niche issue, but we are building a headless solution where the presentation layer is hosted on Netlify, when in a regular...

Minesh Shah (Netcel) | Dec 17, 2025

A day in the life of an Optimizely OMVP - OptiGraphExtensions v2.0: Enhanced Search Control with Language Support and Synonym Slots

Supercharge your Optimizely Graph search experience with powerful new features for multilingual sites and fine-grained search tuning. As search...

Graham Carr | Dec 16, 2025

A day in the life of an Optimizely OMVP - Optimizely Opal: Specialized Agents, Workflows, and Tools Explained

The AI landscape in digital experience platforms has shifted dramatically. At Opticon 2025, Optimizely unveiled the next evolution of Optimizely Op...

Graham Carr | Dec 16, 2025

Optimizely CMS - Learning by Doing: EP09 - Create Hero, Breadcrumb's and Integrate SEO : Demo

  Episode 9  is Live!! The latest installment of my  Learning by Doing: Build Series  on  Optimizely Episode 9 CMS 12  is now available on YouTube!...

Ratish | Dec 15, 2025 |

Building simple Opal tools for product search and content creation

Optimizely Opal tools make it easy for AI agents to call your APIs – in this post we’ll build a small ASP.NET host that exposes two of them: one fo...

Pär Wissmark | Dec 13, 2025 |