A Closer Look at the AvailablePageTypes Attribute in EPiServer 7
I was recently looking into how to fully use the [AvailablePageTypes]
attribute in my page models, and after a bit of research and reading the sometimes confusing documentation, and the less confusing class documentation, I found it has some interesting and helpful features. Let's take a closer look at this attribute.
Update: If you are using EPiServer 7.5+, this attribute is now called AvailableContentTypes
Using the Attribute
As you could guess, this attribute is used to specify which page types can or cannot be created under an instance of a specific page type. This is an optional attribute, but it can drastically help organize the 'Create New Page' screen, while also preventing editors from creating pages in the wrong area. This attribute is not supported on block models.
Availability
The first parameter in the attribute is Availability. This parameter takes one value from the Availability
enum found in the EPiServer.DataAbstraction.PageTypeAvailability
namespace. There are four possible options:
- All - This specifies that all page types will be available to be created under a page instance. This is the default value.
- None - This specifies that no page types will be available to be created under a page instance. If this value is set, all other settings on the attribute are ignored.
- Specific - This specifies that only the selected page types will be created under a page instance. This value makes more sense when configuring available page types in Admin Mode. (My guess is that when any of the other settings on the attribute is set, this value gets auto-selected.)
- Undefined - You shouldn't use this, as it's not even an option in Admin Mode.
Include and Exclude
The two most common parameters for this attribute are Include and Exclude, both of which require an array of Types. One common example would be on a Start Page model:
[ContentType(GUID = "00000000-0000-0000-0000-000000000000")]
[AvailablePageTypes(
Include = new Type[]{ typeof(StandardPage), typeof(ListPage) },
Exclude = new Type[]{ typeof(StartPage), typeof(SettingsPage) }
)]
public class StartPage : PageData
{
}
In this page model, we are saying that we will allow any pages of type StandardPage
and ListPage
to be created, and we will not allow any pages of type StartPage
or SettingsPage
to be created.
Pretty simple and straightforward in my opinion.
IncludeOn and ExcludeOn
These parameters were a bit tricky to understand at first, primarily because the explanation in the documentation is a little confusing.
IncludedOn differs from Include in the way that it is not excluding. That is. for types in IncludedOn that has all page types available no page types will be excluded. Include on the other hand will exclude all typed pages except the ones given in Include.
Excluded works so that if no types are set on Included then the result will be that all registered page types except the Excluded ones are available. If there are types registered in Included then all types in Included except the ones in Excluded are available. Below is an image that shows how Excluded and ExcludedOn are mapped to settings in admin mode.
This is how I see it:
You would use IncludeOn
to specify that the current page type can be created under the specified page type(s). So for our example, we could use the IncludeOn
parameter in the StandardPage
to specify that it can be created under any page instance of the StartPage
page type:
[ContentType(GUID = "00000000-0000-0000-0000-000000000000")]
[AvailablePageTypes(
IncludeOn = new Type[]{ typeof(StartPage) }
)]
public class StandardPage : PageData
{
}
Similarly, you would use ExcludeOn
to specify that the current page type can not be created under the specified page type(s). So for our example, we could the the ExcludeOn
parameter in the SettingsPage
to specify that it can not be created under any page instance of the StartPage
page type:
[ContentType(GUID = "00000000-0000-0000-0000-000000000000")]
[AvailablePageTypes(
ExcludeOn = new Type[]{ typeof(StartPage) }
)]
public class SettingsPage : PageData
{
}
So think of these parameters as a vice-versa of Include
and Exclude
. By using these parameters, you can keep the array of Types short and concise, while also reducing the need to go back and revise the Include
or Exclude
Type arrays of the other page model.
How the Attributes are Applied
With this attribute potentially spread across all of your page models, you might start finding yourself either conflicting or being redundant with your Include
, IncludeOn
, Exclude
, and ExcludeOn
parameters.
If that's the case, keep in mind how the attributes are applied:
Include
implicitly excludes all page types not in the listExclude
implicitly includes all page types not in the listIncludeOn
andExcludeOn
combine with the settings on the target page type- If there is a conflict,
Exclude
andExcludeOn
have priority overInclude
andIncludeOn
.