About a week ago I wrote about, and offered download of, an experimental project called PageTypeBuilder which enabled page type inheritance and strongly typed property access. Since then I’ve done some refactoring and I have also added quite a lot of features to the project. The new version, 0.5 (the old one was 0.1 to signal that it was just an experiment), is downloadable here. While quite a lot of work still remains it’s starting to mature from just an experiment to something that might some day become a beta version ;) Here’s what I’ve done:
Renaming of page types
The PageTypeDefinitionAttribute class has been renamed to PageTypeAttribute and to it I’ve added a Guid property. If we specify a GUID, either by checking what Guid an existing page type has or by adding a new one we can now rename page types by simply changing the name property of the PageType attribute or by renaming the class if we haven’t specified a name.
[PageType("bb6737e6-ccb4-4584-b8ce-3c62ba4ea599")]
public class StartPage : PageData
{
}
The above code will add a page type called Startpage:
We then change the name to “My Start Page”, like this:
[PageType("bb6737e6-ccb4-4584-b8ce-3c62ba4ea599",
Name="My Start Page")]
public class StartPage : PageData
{
}
If we hadn’t specified a GUID a new page type would have been created but now the existing page type is renamed:
I haven’t found a native way to create GUIDs in Visual Studio but the below macro does the trick.
Public Module GUIDGeneratorModule
Sub Create_GUID()
DTE.ActiveDocument.Selection.Text =
System.Guid.NewGuid().ToString()
End Sub
End Module
Specifying Page Type settings
With the previous version a few page type settings such as name and filename could be set. In this new version every setting that can be set in EPiServers admin mode can be set in code using the PageType attribute. I’m especially found of the AvailablePageTypes property which corresponds to the Settings –> Available Page Types tab in admin mode as it accepts an array of types as parameter value.
Here are a few usage examples:
[PageType("bb6737e6-ccb4-4584-b8ce-3c62ba4ea599",
AvailablePageTypes = new [] { typeof(StartPage) },
AvailableInEditMode = false, Filename = "/Default.aspx",
DefaultPageName = "Welcome to the site",
DefaultChildSortOrder = FilterSortOrder.PublishedAscending)]
public class StartPage : PageData
{
}
Specifying property settings
Just as with page types the previous version allowed us to set some settings for properties but far from all. With this version we can set all settings for page type properties that can be set in edit mode except those that are specific for long strings and XHTML strings, from code. This is done by setting values for properties of the PageTypeProperty attribute (renamed from PropertyDefinition in the previous version). A few examples:
[PageTypeProperty(SortOrder = 1, UniqueValuePerLanguage = true,
DisplayInEditMode = true, DefaultValue = "Hello world!")]
public string MainBody
{
//Implementation
}
Undefined properties are removed
In the previous version undefined properties, that is page type properties that where not defined in the corresponding class, where not removed. In this version they are. This means that if you add a property to a page type through code and then remove it from the code, or if you add it from admin mode, it will be removed the next time page types are synchronized, which happens when EPiServer CMS starts up.
Attribute inheritance
Another nice addition in this version is that the PageTypeBuilder now checks for PageType attributes and PageTypeProperty attributes and attributes that inherit from them. This means that it’s possible to create custom attributes with some default values set. Let’s for instance say that we want to have the Unique value per language setting set to true for all of our string properties. We could handle this to some extent with page type inheritance but if some pages have different string properties than those in our base class we’d have to specify this setting for them. Using attribute inheritance we can now simply create our own subclass of the PageTypePropertyAttribute class and use that for all of our string properties, like this:
public class PageTypeStringPropertyAttribute
: PageTypePropertyAttribute
{
public PageTypeStringPropertyAttribute()
{
UniqueValuePerLanguage = true;
}
}
What’s next
While I think it’s starting to look pretty usable by now there are still some major issues to figure out before the PageTypeBuilder project can be considered somewhat complete. It still needs to be able to handle dynamic properties and long string/XHML string settings for example.
Any feedback on how it can be improved is greatly appreciated!
Request for feedback
I initially thought I’d make the GUID mandatory for both page types and properties, but I then found out that properties (PageDefinitions) doesn’t have GUIDs (pleeeaaase EPiServer, add that ;-)) which made me a bit disheartened and therefore I didn’t make it mandatory for page types either. I’m still contemplating making it mandatory though and any feedback on that, and in general, would be greatly appreciated!
Download
The source code for the PageTypeBuilder version 0.5, and a compiled assembly, can be downloaded here.