all things Sitecore related

Sitecore Custom Rules Engine Condition to compare two profile key values

Hi there,

First of all, let me introduce myself on the Newguid.net Sitecore blog. My name is Robbert Hock and I’m a freelance and passionate Sitecore developer living in The Netherlands. I’m running my own business called Kayee Internet & Software Oplossingen and am specialized in Sitecore and Umbraco implementations. In 2011 I was awarded the Sitecore MVP award.

On a regular basis I will be blogging on the Newguid.net blog on things that reflect Sitecore and I think are worth mentioning.

Okay, let’s get to the point what this blog post is all about:

For a CMS battle between Umbraco and Sitecore that I did recently on may 24th 2012 I showed a Sitecore personalization demo. In that demo I wanted to be able to compare profile key values with each other. After some research I noticed (at least I couldn’t find it) that there was no condition available for comparing two profile key values with each other. There is however a conditional rendering rule for comparing a value for a profile key called: Sitecore.Analytics.Rules.Conditions.ProfileCondition, but not for comparing two values with each other however.
But this was really simple to do by creating your own custom OperatorCondition.

  • Add a new Class Library project called (in my case): Kayee.Sitecore.Conditions

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 001

  • Add a reference to the Sitecore.Kernel.dll and the Sitecore.Analytics.dll for the new project.
  • Add a new File to the project called: ProfileKeyGreaterThanProfileKeyCondition, cause that what’s the condition will be used for. Make sure you have Sitecore Rocks installed which will install a lot of templates for all kinds of needs. Go to the Sitecore->Rules item and base the new item upon the Rule Condition template.

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 002

  • Click on Add. A new file will be generated:


using Sitecore.Rules;
using Sitecore.Rules.Conditions;

namespace Kayee.Sitecore.Conditions
{
// TODO: Created Sitecore Item "/sitecore/system/Settings/Rules/Common/Conditions/ProfileKeyGreaterThanProfileKeyCondition" when creating ProfileKeyGreaterThanProfileKeyCondition class. Fix Text field.

public class ProfileKeyGreaterThanProfileKeyCondition<T> : WhenCondition<T> where T : RuleContext
{
protected override bool Execute(T ruleContext)
{
// Return true, if the condition is satisfied.
return false;
}
}
}

With reflector I just saw how the class Sitecore.Analytics.Rules.Conditions.ProfileCondition is coded. Because our class adds just another profilekey, we can use this code and adjust it as the code below:


using System;
using System.Linq;
using Sitecore.Analytics;
using Sitecore.Analytics.Data.DataAccess;
using Sitecore.Analytics.Data.DataAccess.DataSets;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Rules;
using Sitecore.Rules.Conditions;

namespace Kayee.Sitecore.Conditions
{
// TODO: Created Sitecore Item "/sitecore/system/Settings/Rules/Common/Conditions/ProfileKeyGreaterThanProfileKeyCondition" when creating ProfileKeyGreaterThanProfileKeyCondition class. Fix Text field.

public class ProfileKeyGreaterThanProfileKeyCondition<T> : OperatorCondition<T> where T : RuleContext
{
// Fields
private string otherProfileKeyId;
private string profileKeyId;

// Methods
public ProfileKeyGreaterThanProfileKeyCondition()
{
profileKeyId = string.Empty;
otherProfileKeyId = string.Empty;
}

// Properties
public string ProfileKeyId
{
get { return (profileKeyId ?? string.Empty); }
set
{
Assert.ArgumentNotNull(value, "profileKeyId");
profileKeyId = value;
}
}

public string OtherProfileKeyId
{
get { return (otherProfileKeyId ?? string.Empty); }
set
{
Assert.ArgumentNotNull(value, "otherProfileKeyId");
otherProfileKeyId = value;
}
}

protected override bool Execute(T ruleContext)
{
Assert.ArgumentNotNull(ruleContext, "ruleContext");

double profileKeyValue = GetProfileKeyValue(ProfileKeyId);
double otherProfileKeyValue = GetProfileKeyValue(OtherProfileKeyId);
switch (base.GetOperator())
{
case ConditionOperator.Equal:
return (profileKeyValue == otherProfileKeyValue);

case ConditionOperator.GreaterThanOrEqual:
return (profileKeyValue >= otherProfileKeyValue);

case ConditionOperator.GreaterThan:
return (profileKeyValue > otherProfileKeyValue);

case ConditionOperator.LessThanOrEqual:
return (profileKeyValue <= otherProfileKeyValue);

case ConditionOperator.LessThan:
return (profileKeyValue < otherProfileKeyValue);

case ConditionOperator.NotEqual:
return !(profileKeyValue == otherProfileKeyValue);
}

return false;
}

private double GetProfileKeyValue(string profId)
{
if (string.IsNullOrEmpty(profId))
{
return 0.0;
}
Item item = Tracker.DefinitionDatabase.GetItem(profId);
if (item == null)
{
return 0.0;
}
Item parent = item.Parent;
if (parent == null)
{
return 0.0;
}
string profileKeyName = item.Name;
string name = parent.Name;
var visitorLoadOptions = new VisitorLoadOptions
{
Start = Tracker.Visitor.GetOrCreateCurrentVisit().VisitorVisitIndex,
Count = 1,
VisitLoadOptions = VisitLoadOptions.Profiles,
Options = VisitorOptions.None
};
Tracker.Visitor.Load(visitorLoadOptions);
VisitorDataSet.ProfilesRow row = Tracker.CurrentVisit.Profiles.FirstOrDefault((r => (string.Compare(r.ProfileName, name, StringComparison.InvariantCultureIgnoreCase) == 0)));
if (row == null)
{
return 0.0;
}
return row.GetValue(profileKeyName);
}
}
}


  •  Now that we have our code in place (see that we’ve created an OperatorCondition instead of a WhenCondition, make sure it builds and make sure that the Kayee.Sitecore.Conditions.dll will be placed in the Website’s bin folder.
  • Now open up the Sitecore Rocks explorer, navigate to the /sitecore/system/Settings/Rules/Conditional Renderings/Conditions/Profiles and Patterns item and start creating a new Custom Condition called: ProfileKeyGreaterThanProfileKeyCondition

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 003

  • Set the following fields in the ProfileKeyGreaterThanProfileKeyCondition

Type:
Kayee.Sitecore.Conditions.ProfileKeyGreaterThanProfileKeyCondition,Kayee.Sitecore.Conditions

Text:
where the value of [profilekeyid,ProfileKey,,specific] profile key [operatorid,Operator,,compares to] the value of [otherprofilekeyid,ProfileKey,,specific] profile key

For more information on the declaration of parameters see: http://newguid.net/sitecore/2011/sitecore-rules-engine-how-to-create-a-custom-condition/

Okay, that’s probably all you need to know for your Sitecore solution. Now let me take a look how I used this custom condition in the demo that I gave. Now that I have my custom condition configured and defined, I now go to my website in the PageEditor:

On the HomePageBlocks control I can fire up the Create/edit the personalization options for this component.

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 004

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 005

A pop-up appears where I can personalize the component. In my scenario, the default block that is shown will contain a CMS entry, one Sitecore entry and one Umbraco entry.

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 006

Now I want to personalize the component. When a certain visitor on my website collects a number of points for the profile key Sitecore (which he earns when he visits Sitecore related pages by going through my homepage to the Sitecore section of my website) I want to show him, the next time he visits the homepage, only Sitecore blocks. Because obviously he’s a Sitecore minded person. But the website visitor could also earn points when visiting the Umbraco related stuff on my website. Once he reaches a certain amount of points for Umbraco and it the points exceed the number of collected points for Sitecore I want to show him (once he visits the homepage again) only Umbraco related blocks, cause obviously he’s more interested in Umbraco then in Sitecore (which he of course in the end will not be Sitecore Custom Rules Engine Condition to compare two profile key values icon wink ).

Okay, here we go:

  • Click on “New Condition”.

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 007

  • Fill in the name for the current condition, in this case it will be a condition for Umbraco minded visitors. See that in my default condition I’ve set the datasource to the General block.

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 008

  • Click on the … select button to select the Associated content for the given condition

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 009

  • Select the Umbraco Block composition and click OK

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 010

  • Now we’re ready to configure the condition. Click on Edit

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 011

  • The Rule Set Editor opens, type profile in the search box (since our custom condition is called: ProfileKeyGreaterThanProfileKeyCondition and contains the word profile). Select our created custom condition.

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 012

  • In the Rule description you can adjust the blue and red underlined words. I’ve configured my Rule decription the following way (notice how I combined my custom rule with the build in rule on the seconde line)

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 013:

So by saying that the value of build up points for the profile key “Umbraco” should be over 50 (you will get 10 points for each visited page that has something to do with Umbraco and that the value should be greater than the value of the Sitecore key, then this condition will apply and the datasource will be activated.

  • Repeat this by generating another Condition called “Sitecore minded” and you end up with the following screen:

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 014

Click on OK to close the Personalize the Component screen. You can test how the component looks when the conditions are met:

  • Sitecore minded: Will be shown a normal Sitecore block item, a Sitecore PageEditor item and a Sitecore Webform for Marketers item.

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 015

  • Umbraco minded: Will be shown a normal Umbraco block item, a Contour item and a Courier item.

Sitecore Custom Rules Engine Condition to compare two profile key values Blog 1 Image 016

During normal website visits, eventually a condition will be met, and the homepage content blocks will be personalized.

That’s it! In this blog post I’ve shown you the great extensibility of Sitecore by adding my own custom Sitecore Rules Engine Condition and the great built in Personalization feature.

Happy trails!

Robbert Hock

Tags: , , , ,

About the Author

About the Author: I'm a Freelance and passionate Sitecore Developer living in The Netherlands. Running my own company Kayee Internet & Software Oplossingen. I am specialized since 2008 in Sitecore and Umbraco implementations. Sitecore MVP since 2011. Founder and member of the Dutch Sitecore User Group. You can follow me on twitter: @kayeeNL. My website: http://www.kayee.nl .

Subscribe

If you enjoyed this article, subscribe now to receive more just like it.

There Are 12 Brilliant Comments

Trackback URL | Comments RSS Feed

Sites That Link to this Post

  1. (@kayeeNL) (@kayeeNL) | June 26, 2012
  2. John West (@sitecorejohn) | June 26, 2012
  3. (@Sitecore_nl) (@Sitecore_nl) | June 27, 2012
  4. Chris van de Steeg (@csteeg) | June 27, 2012
  5. (@new_guid) (@new_guid) | June 27, 2012
  6. (@markvanaalst) (@markvanaalst) | June 27, 2012
  7. (@pieterbrink123) (@pieterbrink123) | June 27, 2012
  8. @kayeeNL | August 10, 2012
  9. Sitecore Blog (@new_guid) | December 7, 2012
  10. Robbert Hock (@kayeeNL) | December 7, 2012
  11. Marc Duiker (@marcduiker) | December 7, 2012
  12. Mike Reynolds (@mike_i_reynolds) | December 7, 2012

Post a Comment

Your email address will not be published. Required fields are marked *

Top