Personalization based on highest ranking profile key

This post will show how to create a personalization based on three profile keys and show different spots based on which profile key currently has the highest score.

We have three categories of products on the site, they are called “Action”, “Advanced” and “Simple”. Based on these categories a product from the category that the user has shown the most interest in should be shown on the first page of the site. I imagine there are about one million ways of achieving this, I will show how to achieve it by using profiles, rules and personalization. First off we need to set up the profile.

Settings up the profile for personalization

Open the marketing center in Sitecore and add a new profile called “Interest profile” under Profiles. Add three profile keys under the newly created profile and call them “Action”, “Advanced” and “Simple”. Assign each profile key a Max value of 10. Otherwise make no changes to the created items.

To be able to profile some items profile cards need to be added. Lets create three of them, corresponding to the profile keys. Call the first one “Action Item View” and assign it the values Action:10, Advanced:2 and Simple:0 into the “Profile Card Value” field. The assumption here is that the user is very interested in Action items and a little interested in advanced items and not interest at all in simple items if he views an action item. Go ahead and create a profile key called “Advanced Item View” (Action:1, Advanced:10, Simple:0) and one called “Simple Item View” (Action:2, Advanced:2, Simple:10).

You should now have something looking similar to this.

profile

Add the profile cards to the products

Each product that should trigger an interest needs to have the respective profile card assigned to its tracking. Find a product in your content tree and click the profile cards icon in the top right of the page.

assignprofilecard

Click “Edit” next to the “Interest Profile” and add the corresponding profile card by clicking it under “Profile Cards”. You can also customize the values of the profile keys here if you want to. But lets keep it simple and just add the profile card. Go ahead and add different profile cards from the interest profile on different products.

Creating a custom condition in rules

Since I want the spot on the first page to show different things based on profile values compared to other profile values a new rule is needed. The condition that comes with Sitecore for comparing profile values only applies to comparing a profile value to a static value. Not very useful in this case, but the condition is what we are going to base the new condition on.

So lets start with the code. Simply create a new class. I created one, copied the code from Sitecore.Analytics.Rules.Conditions.ProfileCondition  and made some adaptations. It ended up like this:

public class ProfileCompareToProfileCondition : OperatorCondition where T : RuleContext
    {
        private string profileKeyId;
        private string profileKeyId2;

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

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

        public ProfileCompareToProfileCondition()
        {
            profileKeyId = string.Empty;
            profileKeyId2 = string.Empty;
        }

        protected override bool Execute(T ruleContext)
        {
            Assert.ArgumentNotNull(ruleContext, "ruleContext");
            double profileKeyValue1 = GetProfileKeyValue(ProfileKeyId);
            double profileKeyValue2 = GetProfileKeyValue(ProfileKeyId2);
            switch (GetOperator())
            {
                case ConditionOperator.Equal:
                    return Math.Abs(profileKeyValue1 - profileKeyValue2) < 0.001;                 case ConditionOperator.GreaterThanOrEqual:                     return profileKeyValue1 >= profileKeyValue2;
                case ConditionOperator.GreaterThan:
                    return profileKeyValue1 > profileKeyValue2;
                case ConditionOperator.LessThanOrEqual:
                    return profileKeyValue1 <= profileKeyValue2;
                case ConditionOperator.LessThan:
                    return profileKeyValue1 < profileKeyValue2;                 case ConditionOperator.NotEqual:                     return Math.Abs(profileKeyValue1 - profileKeyValue2) > 0.001;
                default:
                    return false;
            }
        }

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

Creating the rule in Sitecore

In order to be able to use the rule in the personalization the newly created condition needs to be added among the rules in Sitecore. Create a new condition under the /sitecore/system/Settings/Rules/Definitions/Elements/Visit item. Call it “Profile Compares To Profile”. Enter the following in the Text field:

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

“profilekeyid” and “profilekeyid2” corresponds to the names in your class and will be set by the values that the administrator chooses for the condition.

Enter the following in the Type field:

MyAssembly.ProfileCompareToProfileCondition,MyAssembly

 Adding personlization

Click the personlization icon for the spot in the page editor (the two little persons with a pen).

personlize

Click “New Condition” in the dialog that appears and select a name for the condition. I called my first condition “Action greatest”. It will be used for showing an action product if the action value is the highest amongst the three profile keys.

Add the new condition by clicking “where the value of the specific profile key compares to specific profile key”. Click the first “specific” and choose the “Action” profile key. Click the “compares to” and choose is greater than and click the second specific and choose the “Advanced” profile key. Add the same condition once more but compare it to the “Simple” profile key instead of the “Advanced” profile key.

Go ahead and add two more conditions based on the same principle but for the other two profile keys. You should now have something that looks like this:

personalization

You are now done! If you show some products with the same profile card assigned to them and return to the home page the spot should change its content accordingly. And if you want to display debug information about the profile values in the current visit you can do so by accessing the profile from code behind and printing it somewhere.

            if (Tracker.CurrentVisit.Profiles.Count() > 0)
            {
                foreach (VisitorDataSet.ProfilesRow row in Tracker.CurrentVisit.Profiles)
                {
                    foreach (KeyValuePair<string, float> keyValuePair in row.Values)
                    {
                        Response.Write(string.Format("{0}, {1} - {2}<br />",  row.ProfileName, keyValuePair.Key, keyValuePair.Value.ToString(CultureInfo.InvariantCulture)));
                    }
                }
            }

Leave a Reply

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