Try our conversational search powered by Generative AI!

Lee Crowe
Oct 18, 2011
  5721
(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
Optimizely and the never-ending story of the missing globe!

I've worked with Optimizely CMS for 14 years, and there are two things I'm obsessed with: Link validation and the globe that keeps disappearing on...

Tomas Hensrud Gulla | Apr 18, 2024 | Syndicated blog

Visitor Groups Usage Report For Optimizely CMS 12

This add-on offers detailed information on how visitor groups are used and how effective they are within Optimizely CMS. Editors can monitor and...

Adnan Zameer | Apr 18, 2024 | Syndicated blog

Azure AI Language – Abstractive Summarisation in Optimizely CMS

In this article, I show how the abstraction summarisation feature provided by the Azure AI Language platform, can be used within Optimizely CMS to...

Anil Patel | Apr 18, 2024 | Syndicated blog

Fix your Search & Navigation (Find) indexing job, please

Once upon a time, a colleague asked me to look into a customer database with weird spikes in database log usage. (You might start to wonder why I a...

Quan Mai | Apr 17, 2024 | Syndicated blog