Sitecore’s Digital Marketing Suite (DMS) is obviously a huge game-breaker in the WCM market. Here’s a tool that is seamlessly integrated into your CMS and allows you to track advanced usage analytics, do multivariate testing on your website, and personalize content on your site so that it is the most effective it can be and your site visitors get the most rewarding experience possible. All that, and if you have needs outside of the out-of-the-box functionality? Don’t worry, like the CMS portion of Sitecore, DMS is built on .NET and fully extensible! The power it gives you is unbelievable, and it’s of course no wonder that Sitecore is seen as the leader in the WCM space per Gartner. Of course, the power that DMS brings can also be a little daunting to. Luckily, if you know where you want to go, and what your business goals are, after getting your feet wet, it’s really not all that bad. This post will help you try getting those toes in the pond by showing an easy to implement custom condition so that Content Author’s can further personalize their sites through Sitecore.
Lots of websites utilize QueryString parameters in one way or another, it’s a generic concept that can apply almost anywhere. So what if our Content Author decided that they wanted to personalize the content of a page on their Sitecore site based on the value of an incoming QueryString parameter? Let’s explore how we’d make this a reality.
Before we begin, let’s identify the components we need to create a QueryString Condition. This is pretty simple, we only need a Sitecore instance of the Condition data template and a corresponding code class to handle the processing. Let’s start with the Sitecore item. First, I’ll navigate to /sitecore/system/Settings/Rules/Conditional Renderings/Conditions in my Sitecore Desktop. I like to keep my custom content separate from that which Sitecore comes with standard, so I’ll insert a new folder under Conditions and call it “Custom Conditions”. Under that “Custom Conditions” folder, I’m going to insert an item of template /sitecore/templates/System/Rules/Condition. I’ll name my new item “QueryStringCondition”. Now I need to populate some fields. The first field I should populate is the “Text” field. I want my Content Author to see the message: “Where the QueryString Parameter [QueryString Name] has a value that [compares to] [QueryString Value]”. In that example message, anything between the brackets will be selectable by the Content Author so that they can customize the condition to meet their specific needs. In a lot of cases, it’s more user friendly to let the Content Author select possible choices from list, but because the nature and usage of QueryString is so broad, I’m OK with simply letting them type in values for the QueryString Name and Value parameters. So, here’s what I need in my text field to get the above output: “Where the QueryString Parameter [QueryStringName,,,QueryString Name] has a value that [operatorid,StringOperator,,compares to] [QueryStringValue,,,QueryString Value]”. The next field I need to populate is type field. I simply populate this field with the [Namespace].[ClassName], [Compiled Assembly] of my corresponding code class. (It helps to create the code class now so that you have that information.) When you’re done, your item should look something like this:
Now we can code our class. We need to create a public class that will do the proper processing – you can find the code for this class below, hopefully it’s self-explanatory (or at least, the embedded comments help you understand what it’s doing):
using System.Web; using Sitecore.Rules; using Sitecore.Rules.Conditions; using Sitecore.Diagnostics; namespace MVCTestSite.Common {
public class QueryStringCondition<T> : StringOperatorCondition<T> where T : RuleContext {
//Properties public string QueryStringName { get; set; } public string QueryStringValue { get; set; } //Methods protected override bool Execute(T ruleContext) {
bool ReturnValue = false; bool FoundExactMatch = false; bool FoundCaseInsensitiveMatch = false; bool FoundContains = false; bool FoundStartsWith = false; bool FoundEndsWith = false; Assert.ArgumentNotNull(ruleContext, "ruleContext"); string myQueryStringName = this.QueryStringName ?? string.Empty; string myQueryStringValue = this.QueryStringValue ?? string.Empty; //Populated with Value selected in Sitecore Rule by Content Author if (!string.IsNullOrWhiteSpace(myQueryStringName)) {
if (HttpContext.Current != null) {
//Populated with QueryString coming into current Page string incomingQueryStringValue = HttpContext.Current.Request.QueryString[myQueryStringName] ?? string.Empty; if (incomingQueryStringValue == myQueryStringValue) {
//Indicates that QueryString coming into Page is equal to QueryString selected by Content Author FoundExactMatch = true; FoundCaseInsensitiveMatch = true; FoundContains = true; FoundStartsWith = true; FoundEndsWith = true;
} else if (incomingQueryStringValue.ToLower() == myQueryStringValue.ToLower()) {
//Indicates that QueryString coming into Page has case-insensitive match to QueryString selected by Content Author FoundCaseInsensitiveMatch = true; //Check other "Found" variables that are not inherently true if (incomingQueryStringValue.Contains(myQueryStringValue)) {
FoundContains = true;
} if (incomingQueryStringValue.StartsWith(myQueryStringValue)) {
FoundStartsWith = true;
} if (incomingQueryStringValue.EndsWith(myQueryStringValue)) {
FoundEndsWith = true;
}
} else if (incomingQueryStringValue.Contains(myQueryStringValue)) {
//Indicates that QueryString coming into Page contains QueryString selected by Content Author FoundContains = true; //Check other "Found" variables that are not inherently true if (incomingQueryStringValue.StartsWith(myQueryStringValue)) {
FoundStartsWith = true;
} if (incomingQueryStringValue.EndsWith(myQueryStringValue)) {
FoundEndsWith = true;
}
}
}
} switch (base.GetOperator()) {
case StringConditionOperator.Equals:
ReturnValue = FoundExactMatch; break;
case StringConditionOperator.NotEqual:
ReturnValue = !FoundExactMatch; break;
case StringConditionOperator.CaseInsensitivelyEquals:
ReturnValue = FoundCaseInsensitiveMatch; break;
case StringConditionOperator.NotCaseInsensitivelyEquals:
ReturnValue = !FoundCaseInsensitiveMatch; break;
case StringConditionOperator.Contains:
ReturnValue = FoundContains; break;
case StringConditionOperator.StartsWith:
ReturnValue = FoundStartsWith; break;
case StringConditionOperator.EndsWith:
ReturnValue = FoundEndsWith; break;
default:
ReturnValue = false; break;
} return ReturnValue;
}
}
}
You won’t believe this…but that’s it! Our Content Author can now personalize their site based off a QueryString Parameter:
I hope after reading the above, you can tell that, while it appears daunting at first, it’s really not hard at all to extend Sitecore DMS to meet your business needs!
Hi Jamie,
This blog is very useful. I followed the same steps as u have mentioned and created a custom rule as “Where the QueryString Parameter SkinType has a value that is equal to Oily Skin”.
My condition name is “QueryStringCondition”.
Then i added the code which u have shared. I wanted to debug, so that i could know that the code is working as expected. When i debug, i am unable to hit the QueryStringCondition class at all.
I have added config in app_config/include.
Do i need to add any more configuration to web.config file?
How do i debug ?
Please help me with this.
Hi Priya. Once you’ve created your class and your condition within Sitecore, the only steps you should have to do to get it to kick off are the following:
1) Make sure you have Sitecore Analytics enabled in configs and have the proper DB connection string in ConnectionStrings.config
2) Utilize your new condition on a presentation detail (rendering / sublayout) using the Sitecore Personalize button on the Page Editor for that presentation detail. (Be sure to save and publish after doing this)
3) Navigate to the page with the presentation detail you just added the condition to while debugging, and your breakpoint should be hit.
That should be it – your condition itself does not require any configuration adjustments.
Hope you get it working, and glad my post could be of assistance!
–Jamie
Pingback: A List of Custom Sitecore DMS Implementations | Sitecore.Context.Item
Pingback: A List of Custom Sitecore DMS Functionality | Sitecore.Context.Item