Don't miss out Virtual Happy Hour this Friday (April 26).

Try our conversational search powered by Generative AI!

Stefan Forsberg
Apr 27, 2009
  6114
(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
Solving the mystery of high memory usage

Sometimes, my work is easy, the problem could be resolved with one look (when I’m lucky enough to look at where it needs to be looked, just like th...

Quan Mai | Apr 22, 2024 | Syndicated blog

Search & Navigation reporting improvements

From version 16.1.0 there are some updates on the statistics pages: Add pagination to search phrase list Allows choosing a custom date range to get...

Phong | Apr 22, 2024

Optimizely and the never-ending story of the missing globe!

I've worked with Optimizely CMS for 14 years, and there are two things I'm obsessed with: Link validation and the globe that keeps disappearing on...

Tomas Hensrud Gulla | Apr 18, 2024 | Syndicated blog

Visitor Groups Usage Report For Optimizely CMS 12

This add-on offers detailed information on how visitor groups are used and how effective they are within Optimizely CMS. Editors can monitor and...

Adnan Zameer | Apr 18, 2024 | Syndicated blog