November Happy Hour will be moved to Thursday December 5th.

Lee Crowe
Oct 18, 2011
  5800
(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 SaaS CMS + Coveo Search Page

Short on time but need a listing feature with filters, pagination, and sorting? Create a fully functional Coveo-powered search page driven by data...

Damian Smutek | Nov 21, 2024 | Syndicated blog

Optimizely SaaS CMS DAM Picker (Interim)

Simplify your Optimizely SaaS CMS workflow with the Interim DAM Picker Chrome extension. Seamlessly integrate your DAM system, streamlining asset...

Andy Blyth | Nov 21, 2024 | Syndicated blog

Optimizely CMS Roadmap

Explore Optimizely CMS's latest roadmap, packed with developer-focused updates. From SaaS speed to Visual Builder enhancements, developer tooling...

Andy Blyth | Nov 21, 2024 | Syndicated blog

Set Default Culture in Optimizely CMS 12

Take control over culture-specific operations like date and time formatting.

Tomas Hensrud Gulla | Nov 15, 2024 | Syndicated blog

I'm running Optimizely CMS on .NET 9!

It works 🎉

Tomas Hensrud Gulla | Nov 12, 2024 | Syndicated blog

Recraft's image generation with AI-Assistant for Optimizely

Recraft V3 model is outperforming all other models in the image generation space and we are happy to share: Recraft's new model is now available fo...

Luc Gosso (MVP) | Nov 8, 2024 | Syndicated blog