Conditional Pages – Part 1
Sunday, June 10, 2012 2:18 PM
A few days ago, I posed a question here (and on Twitter and on the SDN forum and some other places) regarding accessing visitor profile data from the HttpRequestBegin pipeline. I promised to post about why I needed to do that once I had everything working, so here’s the story. Sorry – it’s a bit of a long one. :)
Recently, an NTT Data client asked me if I could do something with Sitecore that I had never imagined before… Essentially, they wanted to A/B test multiple pages across a visit to their site. If a visitor saw homepage A, they would also see the “A” versions of landing pages, etc. The changes between versions were not minor – every rendering on a page was likely to change between the “A” and “B” version, some renderings would use completely different datasource templates, etc.
First, let me say - I completed OMS training and certification a year and a half ago, but this was my first real marketing suite request. The client’s site is being built on current Sitecore 6.5, meaning the latest DMS features were available - but I had little familiarity with them. I’ve developed a working solution, but I imagine there may be a better way to accomplish it. If you know of one, I would love to hear about it!
Anyhow - I could not figure out a way to do this with stock DMS features (based on my limited experience), but eventually I thought of a simple customization that would make it possible… A custom rules engine condition that would check a visitor’s profile for a “Page Design” key with a value of “A” or “B”. If they did not yet have a value, randomly choose one, save it to their profile, and then make a comparison.
The Page Design Condition
With this in place, I was able to set personalization rules on multiple renderings on a page, and have them each evaluate my custom condition (e.g. except where the visitor’s page design is “A”, hide component – see above screenshot). This worked, but it made a crazy mess for content authors within the page editor… Both versions of the page were visible at the same time and it was terribly confusing to try and determine which renderings were meant to appear on which page version, much less edit any content.
Back to the drawing board, then. What I needed was a way to create two separate items in the content tree so they could be edited separately, but allow them to share the same URL or have an alias that redirected to them without changing the URL seen by visitors. I went down many dead end roads trying to realize this idea, but the concept I ended up with is what I’m calling a “conditional page” – an item with rules applied (when the visitor’s page design is “A”, change the current item to “Homepage A”. When the visitor’s page design is “B”, change the current item to “Homepage B”) that changes Sitecore’s context item to allow the page that was requested (the conditional page) to appear as the alternate page.
I present for you here the working solution I eventually landed upon.
A conditional page defines a set of rules under which the site visitor may be “redirected” to another item which will then appear to the visitor in place of the originally requested page.
The above screenshot is of an item using the Conditional Page data template. It is named “demo” and is a child of the site’s homepage. Here, I am using the page design condition discussed above along with a custom action that causes the Sitecore context item to change (I’ll discuss how momentarily). The effect is that when a visitor goes to the /demo URL, they will see either Landing Page A or Landing Page B depending on which page design has been chosen for them during their visit.
The Conditional Page data template has just one field – Rules – of type “Rules”. The Source for this field is set to a folder I created under /sitecore/system/Settings/Rules named “Conditional Page”. This folder has sub-folders named Actions and Conditions containing my custom actions and condition respectively. For more information about this folder structure, you can read John West’s blog post about using the rules engine here http://goo.gl/aadSf
The key to making conditional pages work was to intercept the initial item request, execute the rules stored in the Rules field, and change Sitecore.Context.Item early enough in the process that everything else would treat it like that was the page requested all along… It took some trial and error (see previous question about the HttpRequestBegin pipeline) and a little help from John West on the SDN forum, but I eventually found just the spot – the StartTracking pipeline just before the ProcessItem processor.
The technical details of how all of this is done will fill up another blog post, so I’ll save that for later (I promise to post in the next day or two). But if you’re really interested now – take a look at John West’s post I linked above where he is doing something similar using the rules engine to change the context device for certain requests.
By the way – conditional pages also work with other DMS conditions, not just my custom “page design” one. So you can have the page that comes up be based on GeoIP rules or if a visitor has achieved a DMS goal or search engine keywords, etc, etc. It’s kind of like a rules-powered alias.
I hope this concept will be useful to someone else. :) If you have any questions, comments, suggestions, etc – please reach out to me on Twitter @williamsk000. Thanks for reading!