Stefan Forsberg
Apr 27, 2009
  6159
(0 votes)

Page Provider – Part two

In this post we’ll create a very simple page provider to get a feel for how it behaves.

The base of creating a page provider is implementing an abstract base class called EPiServer.Core.PageProviderBase. Below I’ve created a class that simply implements the abstract methods.

   1: public class CategoryPageProvider : EPiServer.Core.PageProviderBase
   2: {
   3:     protected override EPiServer.Core.PageReferenceCollection GetChildrenReferences(EPiServer.Core.PageReference pageLink, string languageID)
   4:     {
   5:         throw new NotImplementedException();
   6:     }
   7:  
   8:     protected override EPiServer.Core.PageData GetLocalPage(EPiServer.Core.PageReference pageLink, EPiServer.Core.ILanguageSelector languageSelector)
   9:     {
  10:         throw new NotImplementedException();
  11:     }
  12:  
  13:     protected override Uri ResolveLocalPage(EPiServer.Core.PageReference pageLink, out Guid guid)
  14:     {
  15:         throw new NotImplementedException();
  16:     }
  17:  
  18:     protected override Uri ResolveLocalPage(Guid pageGuid, out EPiServer.Core.PageReference pageLink)
  19:     {
  20:         throw new NotImplementedException();
  21:     }
  22: }

So these are the four methods we need to create:

GetChildrenReferences

This method is responsible for fetching the children of a specific page provider page.

GetLocalPage

This method handles the “translation” of our data source into an episerver page (page name and various other properties).

ResolveLocalPage

Two overloads exists for this method that are used to map between page references and guids (an episerver page has both an integer ID and a Guid ID).

Web.config

To register the page provider a new section has to be added in web.config (anywhere directly under the episerver section).

   1: <pageProvider>
   2:     <providers>
   3:         <add name="" type="" entryPoint="" capabilities=""/>
   4:     </providers>
   5: </pageProvider>

Name

Well…the name of the page provider

Type

Points to the page provider class and it’s assembly.

EntryPoint

This refers to the id of the episerver page that should work as a container for your page provider.

Capabilities

We need to inform episerver which level of functionality our page provider supplies. A list of the different capabilities is available here.

 

A simple provider

Instead of jumping into the database and fetch the data there I’m going to start with a purely static data version to show the methods discussed above. In this example we have just two pages, a parant page and a child page. Let’s jump straight into the code.

I’ve created a struct to hold my page data (this represents my custom data source) and created two variables (parentPage and childPage) with some bogus data.

   1: private static Development.DataAbstraction.SimplePage parentPage = new EPiServer.Development.DataAbstraction.SimplePage()
   2: {
   3:     ID = 1000,
   4:     Guid = Guid.NewGuid(),
   5:     Name = "Parent page"
   6: };
   7:  
   8: private static Development.DataAbstraction.SimplePage childPage = new EPiServer.Development.DataAbstraction.SimplePage()
   9: {
  10:     ID = 1001,
  11:     Guid = Guid.NewGuid(),
  12:     Name = "Child page"
  13: };

We also create a static reference to the page type we want to work with in this example

   1: private static PageType standardPageType = PageType.Load(3);

GetChildrenReferences

   1: protected override EPiServer.Core.PageReferenceCollection GetChildrenReferences(EPiServer.Core.PageReference pageLink, string languageID)
   2: {
   3:     PageReferenceCollection pageReferenceCollection = new PageReferenceCollection();
   4:  
   5:     // If the page link points to the entry point (that we defined in web.config) we
   6:     // add our parent page to the collection of page references. Notice that we use
   7:     // a method in the base class called ConstructPageReference for this
   8:  
   9:     // if the page links points to our parent page we add our child page 
  10:     if (pageLink == base.EntryPoint)
  11:     {
  12:         pageReferenceCollection.Add(base.ConstructPageReference(parentPage.ID));
  13:     }
  14:     else if(pageLink.ID == parentPage.ID)
  15:     {
  16:         pageReferenceCollection.Add(base.ConstructPageReference(childPage.ID));
  17:     }
  18:  
  19:     return pageReferenceCollection;
  20: }

 

GetLocalPage

In this method we create an instance of a page data object and call this base method called InitializePageData. This method takes a boat load of parameters that among other things are used to map our data to a episerver page type and create an URL Segment (used for the furl of the page) . The last parameter is used in multi language scenarios but since we’re lazy here and work only with one language we can just send in an empty list of strings.

This is also the method in which you map all the other properties to the page data object. For instance if we wanted to populate the MainBody property of the standard page this is we would do it. More on that in a following post.

   1: protected override EPiServer.Core.PageData GetLocalPage(EPiServer.Core.PageReference pageLink, EPiServer.Core.ILanguageSelector languageSelector)
   2: {
   3:     PageData pageData = new PageData();
   4:  
   5:     Development.DataAbstraction.SimplePage activeSimplePage = GetSimplePage(pageLink);
   6:     
   7:     // Finds the parent to our page.
   8:     PageReference parentLink = (pageLink.ID == parentPage.ID) ? base.EntryPoint : base.ConstructPageReference(parentPage.ID);
   9:  
  10:     base.InitializePageData(
  11:         pageData, 
  12:         activeSimplePage.Name, 
  13:         standardPageType.Name, 
  14:         activeSimplePage.Guid, 
  15:         pageLink, 
  16:         parentLink, 
  17:         new List<string>() {}
  18:         );
  19:  
  20:     return pageData;
  21: }

ResolveLocalPage

The method GetSimplePage tries to fetch the page that’s connected to the sent in page link. This method returns a null object if no suitable page is found. We check if the returned object is our null object and if it is we return null. The reason for doing this is that our page provider might be inquired on pages that does not belong to our page provider so we need a way to let episerver know that this request probably is referring to another page provider.

If in fact the page is “ours” we set the guid to the value of the corresponding SimplePage and use a base method to return the Uri.

   1: protected override Uri ResolveLocalPage(EPiServer.Core.PageReference pageLink, out Guid guid)
   2: {
   3:     var activeSimplePage = GetSimplePage(pageLink);
   4:  
   5:     if (activeSimplePage.Equals(Development.DataAbstraction.SimplePage.NullSimplePage))
   6:     {
   7:         guid = Guid.Empty;
   8:         return null;
   9:     }
  10:  
  11:     guid = activeSimplePage.Guid;
  12:     return base.ConstructPageUri(standardPageType.ID, pageLink);
  13: }

The other overload looks very similar

   1: protected override Uri ResolveLocalPage(Guid pageGuid, out EPiServer.Core.PageReference pageLink)
   2: {
   3:     var activeSimplePage = GetSimplePage(pageGuid);
   4:  
   5:     if (activeSimplePage.Equals(Development.DataAbstraction.SimplePage.NullSimplePage))
   6:     {
   7:         pageLink = PageReference.EmptyReference;
   8:         return null;
   9:     }
  10:  
  11:     pageLink = base.ConstructPageReference(activeSimplePage.ID);
  12:     return base.ConstructPageUri(standardPageType.ID, pageLink);
  13: }

Web.config

This is the section in web.config

   1: <pageProvider>
   2:   <providers>
   3:     <add name="CategoryPageProvider" type="EPiServer.Development.Core.CategoryPageProvider, EPiServer.Templates.Public" entryPoint="26" capabilities="None"/>
   4:   </providers>
   5: </pageProvider>

Result

If we look in episerver now we can see our two pages under the page we definied as an entry point.

episs1

If you hover one of our provider pages we see that is in fact connected to the CategoryPageProvider.

episs12

All the built in episerver controls, FUrl-handling etc works out of the box because as far as the controls know the page is a normal episerver page.

episs2

Apr 27, 2009

Comments

Veerle Verheyen
Veerle Verheyen Sep 27, 2011 09:30 AM

I'm working in CMS 6 R2 and I get errors on "Development.DataAbstraction.SimplePage", could this be deprecated or replaced?

Please login to comment.
Latest blogs
Opti ID overview

Opti ID allows you to log in once and switch between Optimizely products using Okta, Entra ID, or a local account. You can also manage all your use...

K Khan | Jul 26, 2024

Getting Started with Optimizely SaaS using Next.js Starter App - Extend a component - Part 3

This is the final part of our Optimizely SaaS CMS proof-of-concept (POC) blog series. In this post, we'll dive into extending a component within th...

Raghavendra Murthy | Jul 23, 2024 | Syndicated blog

Optimizely Graph – Faceting with Geta Categories

Overview As Optimizely Graph (and Content Cloud SaaS) makes its global debut, it is known that there are going to be some bugs and quirks. One of t...

Eric Markson | Jul 22, 2024 | Syndicated blog

Integration Bynder (DAM) with Optimizely

Bynder is a comprehensive digital asset management (DAM) platform that enables businesses to efficiently manage, store, organize, and share their...

Sanjay Kumar | Jul 22, 2024

Frontend Hosting for SaaS CMS Solutions

Introduction Now that CMS SaaS Core has gone into general availability, it is a good time to start discussing where to host the head. SaaS Core is...

Minesh Shah (Netcel) | Jul 20, 2024

Optimizely London Dev Meetup 11th July 2024

On 11th July 2024 in London Niteco and Netcel along with Optimizely ran the London Developer meetup. There was an great agenda of talks that we put...

Scott Reed | Jul 19, 2024