November Happy Hour will be moved to Thursday December 5th.

Stefan Forsberg
Apr 27, 2009
  6233
(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
Optimizely SaaS CMS + Coveo Search Page

Short on time but need a listing feature with filters, pagination, and sorting? Create a fully functional Coveo-powered search page driven by data...

Damian Smutek | Nov 21, 2024 | Syndicated blog

Optimizely SaaS CMS DAM Picker (Interim)

Simplify your Optimizely SaaS CMS workflow with the Interim DAM Picker Chrome extension. Seamlessly integrate your DAM system, streamlining asset...

Andy Blyth | Nov 21, 2024 | Syndicated blog

Optimizely CMS Roadmap

Explore Optimizely CMS's latest roadmap, packed with developer-focused updates. From SaaS speed to Visual Builder enhancements, developer tooling...

Andy Blyth | Nov 21, 2024 | Syndicated blog

Set Default Culture in Optimizely CMS 12

Take control over culture-specific operations like date and time formatting.

Tomas Hensrud Gulla | Nov 15, 2024 | Syndicated blog