Lee Crowe
Oct 18, 2011
  5748
(4 votes)

PageTypeBuilder 2 – New Features

PageTypeBuilder v2.0 comes with a number of new features which Joel will most probably have already blogged about, see links on this page. But I thought I would put my own post up detailing some of the additional features I have been working on.  I know PageTypeBuilder v2.0 is currently in a Release Candidate state (v1.9.3) but I thought it would be useful before a stable version is released to make users aware of some of the features that may not yet have been documented anywhere and try them out.

Features are detailed below:

1. Page Type Property Groups
2. AvailablePageTypes and ExcludedPageTypes
3. New properties and method added to TypedPageData
4. Explicitly specified Page Type and Page Definition properties will only be updated
5. New GetProperty Extension methods

 

1. Page Type Property Groups

Property groups give the developer the ability to defined reusable groups of properties that can be re-used on Page Types.

We concluded the most important feature to us that was missing was the ability to have reusable groups of properties that could be re-used on Page Types.

If for example I had an Image Link component that I wanted to use on various page types I would first create an ImageLink class that will inherit PageTypePropertyGroup.  You will notice that the properties within the class will be implemented in the same way you would on a page type by decorating the properties with the PageTypeProperty attribute like the following:

  1: public class ImageLink : PageTypePropertyGroup
  2: {
  3:     [PageTypeProperty(
  4:         EditCaption = "Image Url", 
  5:         SortOrder = 0, 
  6:         Type = typeof(PropertyImageUrl))]
  7:     public virtual string ImageUrl { get; set; }
  8:       
  9:     [PageTypeProperty(
 10:         EditCaption = "Link Url", 
 11:         SortOrder = 10, 
 12:         Type = typeof(PropertyUrl))]
 13:     public virtual string LinkUrl { get; set; }
 14: 
 15:     [PageTypeProperty(
 16:         EditCaption = "Alt text", 
 17:         SortOrder = 20, 
 18:         Type = typeof(PropertyString))]
 19:     public virtual string AltText { get; set; }
 20: 
 21:     [PageTypeProperty(
 22:         EditCaption = "Opens in new window",
 23:         SortOrder = 20,
 24:         Type = typeof(PropertyBoolean))]
 25:     public virtual bool OpensInNewWindow { get; set; }
 26: 
 27:     public string GetHtml()
 28:     {
 29:         if (string.IsNullOrEmpty(ImageUrl))
 30:             return string.Empty;
 31: 
 32:         string url = string.IsNullOrEmpty(LinkUrl) ? "#" : LinkUrl;
 33:         string target = string.Empty;
 34: 
 35:         if (OpensInNewWindow)
 36:             target = " target=\"_blank\"";
 37: 
 38:         return string.Format("<a href=\"{0}\" title=\"{1}\"{2}><img src=\"{3}\" alt=\"{1}\" /></a>",
 39:                              url, AltText, target, ImageUrl);
 40:     }
 41: }

We can then add the ImageLink property groups properties to a page type in the following way:

  1: [PageType(
  2:     Name = "[Public] PTB Property groups",
  3:     Filename = "~/MultiplePropertyExample/Pages/PTB.aspx",
  4:     AvailableInEditMode = true)]
  5: public class PropertyGroupsPageType : TypedPageData
  6: {
  7:     [PageTypePropertyGroup(
  8:         EditCaptionPrefix = "Image link one - ",
  9:         StartSortOrderFrom = 400,
 10:         Tab = typeof(TabGeneral))]
 11:     public virtual ImageLink ImageLinkOne { get; set; }
 12:      
 13:     [PageTypePropertyGroup(
 14:         EditCaptionPrefix = "Image link two - ", 
 15:         StartSortOrderFrom = 500,
 16:         Tab = typeof(TabGeneral))]
 17:     public virtual ImageLink ImageLinkTwo { get; set; }
 18: }

You will see in the code sample above that when adding the property group to the page type you will need to decorate the property with the PageTypePropertyGroup attribute.

The PageTypePropertyGroup has the following two properties:

  • EditCaptionPrefix – This defines a prefix which will be added to the edit caption.  If the code above was used an example of a rendered edit caption would be “Image Link one – Image Url.
  • StartSortOrderFrom – This property is used to define the starting sort order for the property group.  If a value for this property has defined the FieldOrder for the property will essentially be the value of PageTypePropertyGroup.StartSortOrderFrom + PageTypeProperty.SortOrder.
  • Tab – This will be the tab that the properties of the property group will appear on in edit mode.

Once the code is compiled and PageTypeBuilder works it’s magic the following properties will be available:

The properties can be accessed within the page in the following way:

  1: <%=CurrentPage.ImageLinkOne.ImageUrl%>
  2: <%=CurrentPage.ImageLinkOne.LinkUrl%>
  3: <%=CurrentPage.ImageLinkOne.AltText%>
  4: <%=CurrentPage.ImageLinkOne.GetHtml()%>

There are also some extension method available for working with the property groups, example usage of these are shown below:

  1: public void Test()
  2: {
  3:     PropertyGroupsPageType pageType = DataFactory.Instance.GetPage(PageReference.StartPage) as PropertyGroupsPageType;
  4:     PropertyData property = pageType.ImageLinkOne.GetPropertyGroupProperty(p => p.ImageUrl);
  5:     PropertyUrl typedProperty = pageType.ImageLinkOne.GetPropertyGroupProperty<ImageLink, PropertyUrl>(p => p.ImageUrl);
  6:     string propertyName = pageType.ImageLinkOne.GetPropertyGroupPropertyName(p => p.ImageUrl);
  7:     pageType.ImageLinkOne.SetPropertyGroupPropertyValue(p => p.ImageUrl, "#");
  8: }

2. AvailablePageTypes and ExcludedPageTypes

All of you will be familiar with the AvailablePageTypes but a new property available on the PageTypeAttribute is ExcludedPageTypes.  Somebody had issued a pull request on github for Joel to merge into the code base but I decided to work along the same lines but implement the changes in my own way.

So with version 2.0 you will now be able to specify available page types or excluded page types.  One useful feature of this is that you don’t have to just specify TypedPageData page types you can also specify TypedPageData base classes and interfaces.

The code below demonstrates how you would specify that only page types that implement the IArticle interface are allowed as children of TestPageType.

  1: public interface IArticle
  2: {
  3: }
  4: 
  5: [PageType(
  6:     Name = "[Public] Test Page Type",
  7:     Filename = "~/MultiplePropertyExample/Pages/PTB.aspx",
  8:     AvailableInEditMode = true,
  9:     AvailablePageTypes = new[] { typeof(IArticle) })]
 10: public class TestPageType : TypedPageData
 11: {
 12: }

 

3. New properties and method added to TypedPageData

The following strongly typed properties have been added to the TypedPageData object, these are missing from the PageData object:

ChangedOnPublish
ChildOrderRule
DelayedPublish
ExternalURL
PeerOrder
ShortcutLink
TargetFrame

TypedPageData now has it’s own implementation of CreateWritableClone which will create a writable clone of the current TypedPageData instance but will also re-instantiate any property groups so that they are pointing to the correct writable PageData instance.

  1: public void Test()
  2: {
  3:     PropertyGroupsPageType pageType = DataFactory.Instance.GetPage(PageReference.StartPage) as PropertyGroupsPageType;
  4:     PropertyGroupsPageType clone = pageType.CreateWritableClone() as PropertyGroupsPageType;
  5:     clone.ImageLinkOne.ImageUrl = "http://www.google.co.uk";
  6: }

 

4. Explicitly specified Page Type and Page Definition properties will only be updated

One of the changes I have made for v2.0 is to only update page type and page definition properties that have explicitly been set in code.

I think a number of people have found it slightly annoying in the past when you have not explicitly set settings within the class/property level attributes but PTB overwrote any changes that were made in Admin mode.

The way I have got round this is to add some internal Boolean properties to both the PageType and PageTypeProperty attributes.  These are only set to true when a property has been specified within one of the attributes.

When the synchronisation occurs for both the page type and property definitions it will firstly check whether the page type or the property is new. 

If the item in question is new it will take any user defined values within the attributes and any default PTB values if values are required but haven’t been set.

If the page type or property already exists then the code will just update any values that have been explicitly set. 

This will allow admins to toggle some properties in edit mode Smile


5. New GetProperty Extension methods

In previous versions there were extension methods for getting property values but there were not any extension methods to get a PropertyData object, these are now available in PTB v2.0.

  1: public void Test()
  2: {
  3:     PropertyGroupsPageType pageType = DataFactory.Instance.GetPage(PageReference.StartPage) as PropertyGroupsPageType;
  4:     PropertyData property = pageType.GetProperty(p => p.ImageLinkOne);
  5:     PropertyUrl typedProperty = pageType.GetProperty<PropertyGroupsPageType, PropertyUrl>(p => p.ImageLinkOne);
  6: }
Oct 18, 2011

Comments

Joel Abrahamsson
Joel Abrahamsson Oct 18, 2011 10:55 AM

Many thanks for posting this, and your great work, Lee!

Please login to comment.
Latest blogs
Opti ID overview

Opti ID allows you to log in once and switch between Optimizely products using Okta, Entra ID, or a local account. You can also manage all your use...

K Khan | Jul 26, 2024

Getting Started with Optimizely SaaS using Next.js Starter App - Extend a component - Part 3

This is the final part of our Optimizely SaaS CMS proof-of-concept (POC) blog series. In this post, we'll dive into extending a component within th...

Raghavendra Murthy | Jul 23, 2024 | Syndicated blog

Optimizely Graph – Faceting with Geta Categories

Overview As Optimizely Graph (and Content Cloud SaaS) makes its global debut, it is known that there are going to be some bugs and quirks. One of t...

Eric Markson | Jul 22, 2024 | Syndicated blog

Integration Bynder (DAM) with Optimizely

Bynder is a comprehensive digital asset management (DAM) platform that enables businesses to efficiently manage, store, organize, and share their...

Sanjay Kumar | Jul 22, 2024

Frontend Hosting for SaaS CMS Solutions

Introduction Now that CMS SaaS Core has gone into general availability, it is a good time to start discussing where to host the head. SaaS Core is...

Minesh Shah (Netcel) | Jul 20, 2024

Optimizely London Dev Meetup 11th July 2024

On 11th July 2024 in London Niteco and Netcel along with Optimizely ran the London Developer meetup. There was an great agenda of talks that we put...

Scott Reed | Jul 19, 2024