Attaching a Page Provider programmatically

blog header image

Configuration vs Code – it’s a classic dilemma. Both have their ups and downs. However, I am the kind of guy that tends to prefer code over configuration (you already guessed, I’m sure). Today I got a question if it’s possible to attach a page provider programmatically – and of course it is. Actually, all you have to do is to instantiate your provider, initialize it and add it to the PageProvider Map in the DataFactory.

If you want to persist over IIS restarts, however you also need to add it to your configuration (in the EPiServerSection.Instance.PageProvider.Providers collection).

I made a very basic example of how to do this. As an example I am using an experimental provider that I haven’t blogged about yet – and which is still a little bit buggy – but it gets the job done :-) I call it the FPWCProvider. Yes…FPWC as in that hated FindPagesWithCriteria method. The idea is that it’s a provider that basically performs an FPWC search and returns the results on it’s first level. So if you for instance want to have a section of your site return a list of the latest press-releases from all over your site, you can simply configure it to search for all Press Release pagetypes and list them there.

In order to attach it on the fly I do a bit of a hack – I have created a PageType called FPWCProvider and whenever people try to create a page of that type, it won’t be created. Instead it’ll attach the page provider to that location. 

Will result in the publishing being cancelled and instead a PageProvider being attached.

The code needed to attach this:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5: using EPiServer;
   6: using EPiServer.Core;
   7: using EPiServer.PlugIn;
   8: using EPiServer.PageProvider;
   9: using System.Collections.Specialized;
  10: using EPiServer.Configuration;
  11:  
  12: namespace EPiServer.PageProviders
  13: {
  14:     public class AttachPageProviders : PlugInAttribute
  15:     {
  16:         public static void Start()
  17:         {
  18:             DataFactory.Instance.PublishingPage += new PageEventHandler(Instance_PublishingPage);
  19:         }
  20:  
  21:         static void Instance_PublishingPage(object sender, PageEventArgs e)
  22:         {
  23:             if (e.Page.PageTypeName == "FPWCProvider")
  24:             {
  25:                 //It's not a page, it's an attachment of a page provider
  26:                 e.CancelAction = true;
  27:  
  28:                 //Attach provider
  29:                 string entrypoint = e.Page.ParentLink.ToString();
  30:  
  31:                 FPWCProvider provider = new FPWCProvider();
  32:                 NameValueCollection config=new NameValueCollection();
  33:                 config.Add("entryPoint", entrypoint);
  34:                 config.Add("name", e.Page.PageName);
  35:                 config.Add("maxCount", e.Page["MaxCount"].ToString());
  36:                 config.Add("propertyName", e.Page["PropertyName"].ToString());
  37:                 config.Add("propertyValue", e.Page["PropertyValue"].ToString());
  38:                 config.Add("propertyType", e.Page["PropertyType"].ToString());
  39:                 config.Add("compareCondition", e.Page["CompareCondition"].ToString());
  40:                 provider.Initialize(e.Page.PageName, config);
  41:  
  42:                 DataFactory.Instance.ProviderMap.AddPageProvider(provider);
  43:                 //TODO: Save the added provider, by adding it to configuration - EPiServerSection.Instance.PageProvider.Providers                
  44:  
  45:             }
  46:         }
  47:     }
  48: }

 

Ok, ok. I bet you are also wondering on the logic of the FPWC provider – so even though it’s unfinished and not really relevant, here you go:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Web;
   5: using EPiServer.Core;
   6: using EPiServer.Filters;
   7:  
   8: namespace EPiServer.PageProvider
   9: {
  10:     public class FPWCProvider : PageProviderBase
  11:     {
  12:         private PropertyCriteriaCollection pcc;
  13:         private PageReferenceCollection pages;
  14:         private int maxCount;
  15:         private FilterSortOrder sortOrder;
  16:  
  17:         public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
  18:         {
  19:             maxCount = int.Parse(config["maxCount"]);
  20:             sortOrder = FilterSortOrder.PublishedDescending;
  21:             if (!string.IsNullOrEmpty(config["sortOrder"]))
  22:             {
  23:                 sortOrder = (FilterSortOrder)Enum.Parse(typeof(FilterSortOrder), config["sortOrder"]);
  24:             }
  25:             pcc = new PropertyCriteriaCollection();
  26:             PropertyCriteria pc = new PropertyCriteria();
  27:             pc.Name = config["propertyName"];
  28:             pc.Required = true;
  29:             pc.Type = (PropertyDataType) Enum.Parse(typeof(PropertyDataType),config["propertyType"]);
  30:             pc.Value = config["propertyValue"];
  31:             pc.Condition = (EPiServer.Filters.CompareCondition) Enum.Parse(typeof(EPiServer.Filters.CompareCondition),config["compareCondition"]);
  32:             
  33:             pcc.Add(pc);
  34:  
  35:             //Setup from config
  36:             base.Initialize(name, config);
  37:  
  38:             //Hook onto publish, move events. Reset Cache
  39:             DataFactory.Instance.PublishedPage += new PageEventHandler(Instance_PublishedPage);
  40:             DataFactory.Instance.MovedPage+=new PageEventHandler(Instance_PublishedPage);
  41:         }
  42:  
  43:         void Instance_PublishedPage(object sender, PageEventArgs e)
  44:         {
  45:             pages = null;
  46:         }
  47:  
  48:  
  49:         protected override void SetCacheSettings(PageReference pageLink, PageReferenceCollection childrenReferences, CacheSettings cacheSettings)
  50:         {
  51:             cacheSettings.CancelCaching = true;
  52:         }
  53:  
  54:  
  55:  
  56:         private PageReferenceCollection GetPages()
  57:         {
  58:             if (pages == null)
  59:             {
  60:                 pages = new PageReferenceCollection();
  61:                 var n = DataFactory.Instance.FindPagesWithCriteria(PageReference.StartPage, pcc);
  62:                 FilterSort fs = new FilterSort(sortOrder);
  63:                 fs.Filter(n);
  64:                 FilterCount fc = new FilterCount(maxCount);
  65:                 fc.Filter(n);
  66:  
  67:                 var t = n.Select(p => p.PageLink).ToArray();
  68:                 pages.AddRange(t);
  69:                 return pages;
  70:             }
  71:             else return pages;
  72:         }
  73:  
  74:         protected override PageReferenceCollection GetChildrenReferences(PageReference pageLink, string languageID)
  75:         {
  76:             if (pageLink == EntryPoint)
  77:             {
  78:                 PageReferenceCollection prc = new PageReferenceCollection();
  79:                 var t=DataFactory.Instance.FindPagesWithCriteria(PageReference.StartPage, pcc).Select(p => p.PageLink).ToArray();
  80:                 prc.AddRange(t);
  81:                 return prc;
  82:             }
  83:             else return new PageReferenceCollection();
  84:         }
  85:  
  86:         protected override PageData GetLocalPage(PageReference pageLink, ILanguageSelector languageSelector)
  87:         {
  88:             return DataFactory.Instance.GetPage(pageLink);
  89:         }
  90:  
  91:         protected override Uri ResolveLocalPage(PageReference pageLink, out Guid guid)
  92:         {
  93:             guid = Guid.Empty;
  94:             return null;
  95:         }
  96:  
  97:         protected override Uri ResolveLocalPage(Guid pageGuid, out PageReference pageLink)
  98:         {
  99:             pageLink = PageReference.EmptyReference;
 100:             return null;
 101:         }
 102:     }
 103: }
Recent posts