Dominik Juszczyk Technical blog

7Jun/082

How to make a page type a ‘leaf’

In one of my projects I had to create page type that was supposed to be a 'leaf' in page tree structure (for this page type no children should be possible to create). First thought was to go to admin mode, to configuration of page types and turn off all page types on "Available page types". I was very surprised that it can't be done. Even if one chooses no page types to be available and save configuration it does not work (when one will open this tab again - all page types will be chosen).
After short investigation I have found post on EPiServer forum. Greger Olofsson describes there some possibilities how this can be achieved. I have tried two of them:

  • create a dummy page type and choose it not to be available in edit mode and then select it as only one available for our 'leaf' page type,
  • subscribe to the CreatingPage event and check what page type name (or id) is used and abort the creation of the new page

Both of them works but have some drawbacks. When selecting dummy page for our 'leaf' page type in edit mode, after clicking 'Create New' link (from context menu or toolbar) we get this page:


It may be confusing for editors because it gives no information why there is no new page page type to choose.
Subscribing to CreatingPage event is not better. I did it with this code (in Global.asax.cs):

protected void Application_Start(Object sender, EventArgs e)
{
EPiServer.DataFactory.Instance.CreatingPage  = new EPiServer.PageEventHandler(OnCreatingPage);
}

private string[] GetLeafPageTypes()
{
string leafPageTypesConfigurationValue =   System.Web.Configuration.WebConfigurationManager.AppSettings["leafPageTypes"];
string delimStr = ",";
char[] delimiter = delimStr.ToCharArray();

return leafPageTypesConfigurationValue.Split(delimiter);
}

protected void OnCreatingPage(object sender, PageEventArgs e)
{
PageData parentPage = EPiServer.DataFactory.Instance.GetPage(e.Page.ParentLink);
foreach (string leafPageType in GetLeafPageTypes())
{
if (parentPage.PageTypeName.ToLower() == leafPageType.ToLower().Trim())
{
e.CancelAction = true;
e.CancelReason = "Page type is lea";
return;
}
}
}

Few words of explanation. I decided to keep configuration which page type is a leaf in web.config which looks like this:

<appSettings>
<add key="leafPageTypes" value="[Public] Start page,[Public] Search page" />
</appSettings>;

It does work and does not allow new page to be created. It does show my warning to the editor ("Page type is a leaf"). But it is done after choosing page type of new page and after pressing Save button (so also after editor has filled in all properties values and after seeing informations which properties are mandatory to fill).

Then for some time I tried to modify context menu (the one that is showing on right mouse button) but I realized that I will also have to modify toolbar (where new page button is present also). And then I decided to do it in NewPage.aspx file located in edit folder. I know that this shouldn't be done mostly because it will be lost (it can be lost to be more specific) during upgrades. But my change is very simply and very easy to add after possible upgrade. What I did? I have added to this page similar code as I tested on CreatingPage event. I have added to markup file those lines:

<%@  Import namespace="EPiServer"%>
<%@  Import namespace="EPiServer.Core" %>
<script runat="server">
private string[] GetLeafPageTypes()
{
string leafPageTypesConfigurationValue =   System.Web.Configuration.WebConfigurationManager.AppSettings["leafPageTypes"];

string delimStr = ",";
char[] delimiter = delimStr.ToCharArray();
return leafPageTypesConfigurationValue.Split(delimiter);
}

protected override void OnLoad(System.EventArgs e)
{
foreach( string leafPageType in GetLeafPageTypes() )
{
if (CurrentPage.PageTypeName.ToLower() == leafPageType.ToLower().Trim())
{
ErrorMessage.Text = "Page type is leaf. Cannot have children";
PageTypeList.Visible = false;
Cancel.Visible = false;
}
}
base.OnLoad(e);
}
</script>

and Label control to display my message:

<asp:Label ID="ErrorMessage" runat="server" ForeColor="red" ></asp:Label>

I'm still using appSettings key to keep configuration which page type are a 'leaf' ones. Now when editor wants to create new page under 'leaf' page type page after clicking "Create New" link he/she sees that information:

So as you can see I achieved two things:

  • it is possible to define page type (or page types) as a 'leaf' by editing one key in web.config
  • it is easy to make page type a 'leaf' just for some time without changing it's configuration (available page types)
  • editor now can see information why he/she can't create new page with chosen parent.

I suppose that there are different way to do something similar. If you know them - please let me know :)

Comments (2) Trackbacks (0)
  1. Humm… interesting,

    I wish I knew some other ways

    Thanks for writing about it

  2. Have you seen this module in EPiCode?https://www.coderesort.com/p/epicode/wiki/NewPage I think that it allows to do it in nice way (configuration via Dynamic properties as far as I remember) and also has more nice features :)


Leave a comment


No trackbacks yet.