Creating an IContentProvider

ContentProviders are simple classes that implement the IContentProvider interface and are marked with the VisitorGroupContentProvider attribute.

Example - building a StartPageChildrenContentProvider

This example content provider will provide a list of all child pages that live directly underneath the defined EPiServer start page.
  • Create your class and implement the IContentProvider members. The only method we have to provide an implementation for is the GetContent method which returns a collection of PageData objects.
public class StartPageChildrenContentProvider : IContentProvider
{
        public IEnumerable<PageData> GetContent(string languageBranch)
        {
            throw new NotImplementedException();
        }

        public Guid VisitorGroupId { get; set; }
        public string ContentCriteria { get; set; }
}
  • Implement the public IEnumerable<PageData> GetContent(string languageBranch) method, in our case this uses the DataFactory API to return the Child pages of the StartPage.
public IEnumerable<PageData> GetContent(string languageBranch)
{
       return DataFactory.Instance.GetChildren(PageReference.StartPage, new LanguageSelector(languageBranch));
}

The above is obviously a simple implementation and doesn't take into account any page access rights. If you wish the ContentProvider to reflect these then you should add them into this method.
  • Mark the class up with a VisitorGroupContentProvider attribute. This attribute allows three arguments
    • DisplayName - a simple description of the ContentProvider
    • Description - a description of what the ContentProvider does
    • CriteriaEditModel - the strongly typed model used to allow editor's to input criteria for use by the ContentProvider - these must inherit from ICriteriaModel. Our simple case doesn't need one and so we can either leave this attribute blank, or specify the DefaultCriteriaModel. For more information see ContentProvider Criteria / EditModels

[VisitorGroupContentProvider(DisplayName = "StartPage children content provider", 
                                Description = "Returns the immediate child pages the live underneath the website Start Page ",
                                CriteriaEditModel = typeof(DefaultCriteriaModel))]  
public class StartPageChildrenContentProvider : IContentProvider
{
...
}

Once you have marked the attribute, the Personalization engine will pick up your ContentProvider on startup and it will be available for Editors to use.

Performance

ContentProviders will generally use the underlying EPiServer API to return PageData objects. Although some calls such as GetChildren used in the above example will already hook into the EPiServer Caching framework and return cached objects, there are some other API calls that will directly hit the database (such as FindPagesWithCriteria). In these cases we must be more careful of performance, as the PersonalizationEngine could perform many GetContent calls on a simgle page.

In these cases, instead of your ContentProvider directly implementing IContentProvider it should instead inherit from the CachedContentProviderBase class. This abstract class itself implements IContentProvider - but also provides one abstract method to override.

protected override IEnumerable<PageReference> GetContentReferences(string languageBranch)
{
...
}

It is EPiServer best practise to NEVER directly cache PageData objects and to instead cache their corresponding PageReferences (see http://joelabrahamsson.com/entry/how-episerver-cms-caches-pagedata-objects for more information). The CachedContentProviderBase class will handle caching the PageReferences returned from this method and preferentially use that cache when returning any calls to GetContent(). The cache is set as a sliding cache of 20 minutes.

Our implementation would now look like

public class StartPageChildrenContentProvider : CachedContentProviderBase
{
        protected override IEnumerable<PageReference> GetContentReferences(string languageBranch)
        {
            var pages = DataFactory.Instance.GetChildren(PageReference.StartPage, new LanguageSelector(languageBranch));
            return pages.Select(p => p.PageLink);
        }
}

Last edited May 8, 2011 at 8:30 PM by ev2000, version 1

Comments

No comments yet.