Calling all developers! We invite you to provide your input on Feature Experimentation by completing this brief survey.

 

Anders Hattestad
Feb 16, 2011
  9650
(2 votes)

Auto create sub page(s) when a page is created

imageThere are times when I want to make a structure of pages when one page is created. Sometimes it would be easy to just add an attributes to your page type, so each time a page of that type is created we will auto magically add a sub page.

 

First I made myself a attribute

Code Snippet
  1. [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
  2. public class EnsureSubPageAttribute : Attribute
  3. {
  4.     public Type PageType { get; set; }
  5.     public string PageName { get; set; }
  6.     public string URLSegment { get; set; }
  7.     public int SortIndex { get; set; }
  8.     public string SetReferenceToProperty { get; set; }
  9.     public string[] SetPropertyNames { get; set; }
  10.     public string[] SetPropertyValues { get; set; }
  11. }

Then I add myself to the Created Page event. I do this stuff there since created page is only triggered once, and if I change my attributes I will ensure my sub pages on startup.

Code Snippet
  1. [ModuleDependency(typeof(PageTypeBuilder.Initializer))]
  2. public class EnsureSubPages : IInitializableModule
  3. {
  4.     #region IInitializableModule Members
  5.     public void Initialize(EPiServer.Framework.Initialization.InitializationEngine context)
  6.     {
  7.         EPiServer.DataFactory.Instance.CreatedPage += new EPiServer.PageEventHandler(Instance_CreatedPage);
  8.         EnsureAllExistingPages();
  9.     }
  10.        
  11.     public void Preload(string[] parameters) { }
  12.  
  13.     public void Uninitialize(EPiServer.Framework.Initialization.InitializationEngine context)
  14.     {
  15.         EPiServer.DataFactory.Instance.CreatedPage -= new EPiServer.PageEventHandler(Instance_CreatedPage);
  16.     }
  17.     #endregion

The method for created page looks like this

Code Snippet
  1. void Instance_CreatedPage(object sender, EPiServer.PageEventArgs e)
  2. {
  3.     EnsureSubPagesForPage(e.Page);
  4. }
  5. static void EnsureSubPagesForPage(PageData page)
  6. {
  7.     var type = page.GetType();
  8.     PageDataCollection subPages = null;
  9.     foreach (var attribute in type.GetCustomAttributes(true))
  10.     {
  11.         var myAttribute = (attribute as EnsureSubPageAttribute);
  12.         if (myAttribute != null && !string.IsNullOrEmpty(myAttribute.URLSegment))
  13.         {
  14.             if (subPages == null)
  15.                 subPages = EPiServer.DataFactory.Instance.GetChildren(page.PageLink, LanguageSelector.MasterLanguage());
  16.             var result = (from subPage in subPages where subPage.URLSegment == myAttribute.URLSegment select subPage).ToList();
  17.             if (result.Count == 0)
  18.                 page = CreatePage(page, myAttribute);
  19.             else
  20.                 UpdatePage(myAttribute, result[0]);
  21.         }
  22.     }
  23.     if (page.IsModified)
  24.         EPiServer.DataFactory.Instance.Save(page, EPiServer.DataAccess.SaveAction.ForceCurrentVersion | EPiServer.DataAccess.SaveAction.Publish, EPiServer.Security.AccessLevel.NoAccess);
  25. }

but the cool (and dangerous ) task is the method that checks all the page types and find all that uses the attribute.Then finds all pages of that type and ensure them.

Code Snippet
  1. private static void EnsureAllExistingPages()
  2. {
  3.     foreach (var pagetype in EPiServer.DataAbstraction.PageType.List())
  4.     {
  5.         var typedPageType = PageTypeResolver.Instance.GetPageTypeType(pagetype.ID);
  6.         if (typedPageType != null && typedPageType.GetCustomAttributes(typeof(EnsureSubPageAttribute), true).Length > 0)
  7.         {
  8.             var pages = FindPagesByPageType(typedPageType, PageReference.StartPage);
  9.             foreach (var page in pages)
  10.                 EnsureSubPagesForPage(page);
  11.         }
  12.     }
  13. }

 

So now one can in the code behind mark page types with attributes like this

Code Snippet
  1. [PageType(Name = "Department structur", Filename = "/Custom/Pages/Department.aspx", DefaultSortIndex = 10)]
  2. [EnsureSubPage(
  3.     PageType = typeof(AttachPageProviderPageType),
  4.     PageName = "Community pages",
  5.     SetPropertyNames=new string[] {"AttachChildrenFrom"},
  6.     SetPropertyValues=new string[] {"22"},
  7.     SetReferenceToProperty = "OneClubPage",
  8.     URLSegment = "CommunityPages",
  9.     SortIndex = 10)]
  10. [EnsureSubPage(
  11.     PageType = typeof(UDPageType),
  12.     PageName = "dummy page",
  13.     URLSegment = "DummyPage",
  14.     SortIndex=20)]
  15. [EnsureSubPage(
  16.     PageType = typeof(UDPageType),
  17.     PageName = "dummy page 2",
  18.     URLSegment = "DummyPage2",
  19.     SortIndex = 30)]
  20. public class DepartmentPageType : TypedPageData, OnCreatedPage, IClubRoot

Full code is here. Its just one file :)

Feb 16, 2011

Comments

Feb 17, 2011 04:03 PM

Neat solution.
I think I'll have to replace my global event handlers with your code.

Please login to comment.
Latest blogs
Image Analyzer with AI Assistant for Optimizely

The Smart Image Analyzer is a new feature in the Epicweb AI Assistant for Optimizely CMS that automates the management of image metadata, such as...

Luc Gosso (MVP) | Jan 16, 2025 | Syndicated blog

How to: create Decimal metafield with custom precision

If you are using catalog system, the way of creating metafields are easy – in fact, you can forget about “metafields”, all you should be using is t...

Quan Mai | Jan 16, 2025 | Syndicated blog

Level Up with Optimizely's Newly Relaunched Certifications!

We're thrilled to announce the relaunch of our Optimizely Certifications—designed to help partners, customers, and developers redefine what it mean...

Satata Satez | Jan 14, 2025

Introducing AI Assistance for DBLocalizationProvider

The LocalizationProvider for Optimizely has long been a powerful tool for enhancing the localization capabilities of Optimizely CMS. Designed to ma...

Luc Gosso (MVP) | Jan 14, 2025 | Syndicated blog