Try our conversational search powered by Generative AI!

Dan Matthews
Nov 20, 2013
  6713
(0 votes)

Restricting available page types for Root page

Now that we have strongly typed page types in EPiServer 7, we wonder how we ever lived without it. Actually… we just used the superb Page Type Builder, but that’s not the point. We now want to do everything in code rather than in the Admin mode, and we nearly can. However, there are a couple of little things that we can’t quite do yet, and restricting the available page types for the Root page is one of them. Typically, you will only ever be creating ‘start pages’ under the Root page, and you’ll probably have a specific type for the start page. If we do a ‘New page’ under the Root though, we get all of our page types listed! That’s a bit messy. So what are our options? Well, the Root page is in Admin mode; it’s called ‘Welcome page in Edit Mode’ and it’s type is ‘SysRoot’. We could restrict available page types there. But that’s going back to the dark ages. You can’t commit that to source control like other code and have it picked up by everyone else. A much nicer way would be to use the AvailablePageTypes attribute. No luck there though – the SysRoot has no code definition that I can find (according to Admin mode it doesn’t come from code) and so you can’t use it with the strongly-typed AvailablePageTypes attribute. Possibly you could create a definition for the SysRoot in code, but that’s a pretty scary thing to do and I personally wouldn’t want to go there – I used to do it in Page Type Builder but I wouldn’t want to in EPiServer 7.

So what do we do? I was asked that by a student in a training course recently, and so I had to comeup with an answer. Actually, it’s pretty easy. We use an Initialization Module and the API to do what Admin mode is doing, but automatically and in code. The code to achieve this is shown below. Note that in this example the start page type is ‘StartPage’.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using EPiServer.Framework;
using EPiServer.ServiceLocation;
using EPiServer.DataAbstraction;
using EPiServerZA.Models.Pages;
 
namespace EPiServerZA.Business
{
    [InitializableModule]
    [ModuleDependency(typeof(EPiServer.Data.DataInitialization))]
    public class RestrictRootPages : IInitializableModule
    {
        public void Initialize(EPiServer.Framework.Initialization.InitializationEngine context)
        {
            var sysRoot = ServiceLocator.Current.GetInstance<IContentTypeRepository>().Load("SysRoot") as PageType;
            var startPage = ServiceLocator.Current.GetInstance<IContentTypeRepository>().Load(typeof(StartPage));
 
            var setting = new EPiServer.DataAbstraction.PageTypeAvailability.AvailableSetting();
 
            setting.Availability = EPiServer.DataAbstraction.PageTypeAvailability.Availability.Specific;
            setting.AllowedPageTypeNames.Add(startPage.Name);
 
            ServiceLocator.Current.GetInstance<EPiServer.DataAbstraction.PageTypeAvailability.IAvailableSettingsRepository>().RegisterSetting(sysRoot, setting);
        }
 
        public void Preload(string[] parameters)
        {
           
        }
 
        public void Uninitialize(EPiServer.Framework.Initialization.InitializationEngine context)
        {
           
        }
    }
}

The code simply grabs the SysRoot and StartPage types from the content type repository then makes the StartPage the only available page type on the SysRoot. There is a dependency on DataInitialization so that the repositories should be ready to use when this runs. Any clarifications or easier ways to achieve this are welcome Smile

Nov 20, 2013

Comments

Al Higgs
Al Higgs Nov 21, 2013 03:45 PM

Nice article Dan!

Al Higgs
Al Higgs Nov 21, 2013 03:46 PM

Very useful to know Dan

thomassvensen
thomassvensen Jan 17, 2014 01:16 PM

Very useful, Dan, thank you!

We are using 7.5.409, and I found they've changed things slightly. My coded ended up looking like this:

var locator = ServiceLocator.Current;
var contentTypeRepository = locator.GetInstance();
var sysRoot = contentTypeRepository.Load("SysRoot") as PageType;
var startPage = contentTypeRepository.Load(typeof(StartPage));
var setting = new AvailableSetting {Availability = Availability.Specific};
setting.AllowedContentTypeNames.Add(startPage.Name);
var availabilityRepository = locator.GetInstance();
availabilityRepository.RegisterSetting(sysRoot, setting);

Feb 11, 2014 08:27 AM

Thanks for the update Thomas, yes it makes sense that it is slightly different in 7.5 as they have abstracted some additional things around content!

Oct 15, 2016 07:29 PM

The code will only work if there actually is a startpage created. A null protect on the startpage variable and the code is usable once again!

var locator = ServiceLocator.Current;
var contentTypeRepository = locator.GetInstance();
var sysRoot = contentTypeRepository.Load("SysRoot") as PageType;
var startPage = contentTypeRepository.Load(typeof(StartpagePage));
if (startPage != null)
{
    var setting = new AvailableSetting { Availability = Availability.Specific };
    setting.AllowedContentTypeNames.Add(startPage.Name);
    var availabilityRepository = locator.GetInstance();
    availabilityRepository.RegisterSetting(sysRoot, setting);
}

Thanks for sharing.

Nov 10, 2016 01:22 PM

Thanks for feedback Eric... I presume you mean start page TYPE created, which you might not have on first time load as it's possible I guess that the start page type hasn't synced into your content type repository BEFORE this loads. Maybe you could change your module dependency to a later one (like EPiServer.Web.InitializationModule) which would probably ensure that you have your StartpagePage type (in your example) already synced into the content type repository before this code runs. Otherwise, this will only pick up and run on your second load :)

Please login to comment.
Latest blogs
New Security Improvement released for Optimizely CMS 11

A new security improvement has been released for Optimizely CMS 11. You should update now!

Tomas Hensrud Gulla | May 7, 2024 | Syndicated blog

Azure AI Language – Key Phrase Extraction in Optimizely CMS

In this article, I demonstrate how the key phrase extraction feature, offered by the Azure AI Language service, can be used to generate a list of k...

Anil Patel | May 7, 2024 | Syndicated blog

Webinar: Get Started with AI within Optimizely CMS

Join us for the webinar "Get Started with AI in Optimizely CMS" on Wednesday, May 8th. Don't forget to register!

Luc Gosso (MVP) | May 7, 2024 | Syndicated blog

Search & Navigation: Indexing job new features

From Episerver.Find version 16.1.0, we introduced some new features that make the indexing job in CMS more flexible and efficient: Support continuo...

Vinh Cao | May 7, 2024

Exclude content from search engines

Best practices for excluding your Optimizely CMS test content from search engines like Google, along with some tips on what to do—and what not to...

Tomas Hensrud Gulla | May 7, 2024 | Syndicated blog

Run imgproxy container on Azure App Service with Front Door CDN

A simple way to host a imgproxy Docker container and use it to get AVIF and WEBP images.

Johan Kronberg | May 5, 2024 | Syndicated blog