This article is a part of the series describing the faceted navigation system for EPiServer that we have developed in Cognifide and that’s already proven to be a robust solution for delivering tagged content a heavy traffic site. The engine will be released shortly as an open source project.

So how is the faceted engine structured?


Content provider

As you can see the driving force behind the engine is the Facet Tagged Content Provider. If you know EPiServer, the basic functionality of the module is roughly an an equivalent of find page with criteria for categories, which allows for searching pages tagged with facets with exclusion of some other facets and tagged some optional data, the module however is paging and and allows you to plug a feedback event handler so that your controls can accept or deny a story before they are sent to is and take part in the paging. The stories are provided to you in reverse order of publishing so you always get the latest stories first, (pretty much what any blog and any news site wants).

Another function of the content provider is assertion of story uniqueness on the page. This is actually a pretty cool mechanism that deserves closer attention.

Let’s imagine a page having a control with “main story” that is pre-selected by an editor, and then some “featured stories” also pre-selected, then there is a control with “latest news concerning facet A” and a “latest news concerning facet B”. The problem with this scenario is that if a story was pre-selected for the “main story” and perhaps then someone added it to “featured stories”, and the story actually is tagged by facet A and facet B – in a traditional search you would normally get it in all of the controls… not cool!

The solution that we’ve come up with is based on a free market rules. And the procedure is as follows:

  1. The request starts and the engine opens a bidding for articles.
  2. All the controls request their interest in stories by either providing the engine with pre-selected stories they would like to display or asking it to provide the freshest content based on the facets the content is tagged with. They also provide it with their value (priority). And a callback for the engine to provide them with the stories.
  3. The acceptance phase ends and the engine distributes the stories looking from the highest value controls down the list in the following way
    • when the control provide the list of articles if so check for each article if it has not been taken yet, and otherwise feed it back to the control
    • otherwise if the control provided it with the facets it’s “interested in” it asks the tagged content store for articles tagged with this context and feeds them to the control if they have not been otherwise provided to another control with higher priority, until it reaches the number requested by the control. (this way of providing articles also allows for paging).
  4. Upon satisfying all the controls the bidding is closed and all articles become available again.

Content Accelerator

Content accelerator is a caching module that we have made mandatory that all of our EPiServer calls must pass through. The engine turns the pages into objects with a well defined and hard typed objects rather than a-bag-of-strings-and-the-likes your usual PageData is.

This makes it much more efficient for us to cache only the important data contained in any given page and only the data that we use frequently, e.g. page name and page URL that are used by URL provider and that are likely to be called multiple times within any given user request. This has been been implemented to compensate for the slowness of GetPage calls.

For that to work effectively we always tread content accelerator as a proxy for GetPage – which allows us to filter any expired or not yet published pages faster and refresh the content and accessibility for everyone, any time any given content is refreshed.

The For this concept to work – any page type that is going to be used in it has to have its own class added to it with the properties you will usually access (this however should be done with caution, for example you can cache article intro, but caching a potentially big article is a bad idea – also a full article text is very unlikely to be displayed on a high traffic page so caching all of your article full texts will not offset for a potential quick running out of memory).

Also the content cache is written using generics in a way that allows you to specify a multiple classes for any page types – the class consuming the cache defines how it wants to treat the content and access it. The different cache classes will then be chain linked and refreshed.

The content expires on an arbitrary set time (1 minute in our case but you can specify any other period), but we’ve also written a web service allowing for expiring a page-cache-item whenever it is changed on any of servers in a multiserver scenario. This for this to work – you have to plug into the global EPiServer event handlers. Which I’ll describe later.

The accelerator is used extensively by the faceted engine, but it can also be used directly and is completely independent of the rest of the faceted engine.

Facet Context Provider

This provides the control with ewasy facility to retrieve the facets with which the request was performed.

Facet URL Provider

This service allows you to construct URLs based on a facet context – with automatic determination of a preferred visualisation (hub page). Naturally you can still force the provider to format the URL for a pre-determined page. The effect will be a request that can later be succesfully parsed by the Context Provider once that URL is executed on the server.

Auto Tagging Module

This block which originally was a separate module is now basically shrunk to a single method that you can plug into EPiServer in the Global.asax. The routine tags a page with facets predefined in its parent, during the process of a page creation. This is useful for tagging e.g. all the “technology” stories with “technology” facet and an “News” facet once its created in the “Technology articles” branch.


Part of the faceted navigation, but not directly part of the engine are editors for facet roles, the very facets and facet selectors.

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)

This entry (Permalink) was posted on Thursday, January 24th, 2008 at 5:18 pm and is filed under .Net Framework, ASP.NET, EPiCode, EPiServer, Faceted Navigation, Open Source, Software, Software Development, Web applications. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response , or trackback from your own site.