Skip to main content

Reusable Business rules

One of the best aspects of Sitecore is its rules engine. It is easy to use and very extensible. I have worked on large projects which run multiple websites one thing that comes up is how can rules, which authors create, be reused? It is great we can add a personalization rule to a rendering but what if we have the same rule we want to apply multiple places? Can we do this in a way we don't have to go change that rule in each place?

One approach to this is using the predefined rules that come with Sitecore. These are located at /sitecore/system/Marketing Control Panel/Personalization/Predefined Rules.


Once you have created a predefined rule you can use it via personalization by click on the "predefined rules" sections when creating a new rule.


Once you have done this you have a reusable rule you can edit in one place but use in lots of different personalization locations. This is great and can be very helpful. However, it only gives you access to the condition, not the actions. So you can reuse the condition (if something true or false) but you don't have access to the actions (what you are personalizing, so a rendering or data source, etc). What if you want a way to reuse the condition and the expected action to execute? 

Out of the box, there is not a way to do this as the only place you can set both are in the presentation details of an item. So you could find a way to do inheritance of presentation details. That is an option and details of presentation or layout inheritance I hope to cover in a different blog. Here are some blogs on that topic if you need that now. Override Sitecore default mechanism of getting presentation details or Inheritance of presentation details

What I am going to focus on here is how to use an item as a data source and have a pipeline execute that rule and inject the personalization results of the rule of that item into your output. First what you are going to do is create a new template that has a "Rule" field that is of type "Rule". 


Nothing fancy here. The "Rules" type is a Sitecore out of the box type that allows you to add a business rule field to an item. This allows you to create a new item that will hold the personalization rule you want to reuse. 


Great, now you have a place to hold the rule you want to reuse, how do you get Sitecore to process and use it? To do this you need a pipeline processor. The below code is how you can do this. Now keep in mind that I am injecting a logging repository in the code so I can log things I care about. So if you are using this you will need to remove that or replace it with your own. 

The logic for this really starts at line 35. Here you get the data source item and see if it is of the template type we care about. If it is we need to inject the rule into the rendering properties the pipeline is going to process. We need to do this in two places in the arguments. We need to update the personalization rules that need to be executed, then we need to update the rendering XML stored in the rendering arguments.   


Once you have your code just patch the processor into the pipeline. 


To help visualize what is happening here think of the presentation details of an item. When you view the raw value of this field for an item you can see it is just XML data about how it is configured. So with this code, we are just pushing the configuration of our reusable rule field into this configuration. 

Now with the below code, the rule you inject will be executed and the data source your rendering ends up showing will be changed based on your rule configuration (or whatever action your rule was configured to take). 


Comments

Popular posts from this blog

Uniting Testing Expression Predicate with Moq

I recently was setting up a repository in a project with an interface on all repositories that took a predicate. As part of this I needed to mock out this call so I could unit test my code. The vast majority of samples out there for mocking an expression predicate just is It.IsAny<> which is not very helpful as it does not test anything other then verify it got a predicate. What if you actually want to test that you got a certain predicate though? It is actually pretty easy to do but not very straight forward. Here is what you do for the It.IsAny<> approach in case someone is looking for that. this .bindingRepository.Setup(c => c.Get(It.IsAny<Expression<Func<UserBinding, bool >>>())) .Returns( new List<UserBinding>() { defaultBinding }.AsQueryable()); This example just says to always return a collection of UserBindings that contain “defaultBinding” (which is an object I setup previously). Here is what it looks like when you want to pass in an exp

Password Management

The need to create, store and manage passwords is a huge responsibility in modern day life. So why is it that so many people do it so poorly? This is a loaded questions with answers ranging from people being uneducated, to lazy, to educated but not affective in their methods and many more. This blog is to help those (in some way even myself) around me strengthen their online security. Why does it matter? To answer this let's look at a few numbers. According to the US Department of Justice (DOJ)’s most recent study , 17.6 million people in the US experience some form of identity theft each year. Ok fine but that is identity theft that has nothing to do with password management. What is one way someone can start getting information about who you are? How do they get access to steal your money? From Cyber Security Ventures 2019 report : "Cybersecurity Ventures predicts that healthcare will suffer 2-3X more cyberattacks in 2019 than the average amount for other industries. W

Excel XIRR and C#

I have spend that last couple days trying to figure out how to run and Excel XIRR function in a C# application. This process has been more painful that I thought it would have been when started. To save others (or myself the pain in the future if I have to do it again) I thought I would right a post about this (as post about XIRR in C# have been hard to come by). Lets start with the easy part first. In order to make this call you need to use the Microsoft.Office.Interop.Excel dll. When you use this dll take note of what version of the dll you are using. If you are using a version less then 12 (at the time of this writing 12 was the highest version) you will not have an XIRR function call. This does not mean you cannot still do XIRR though. As of version 12 (a.k.a Office 2007) the XIRR function is a built in function to Excel. Prior version need an add-in to use this function. Even if you have version 12 of the interop though it does not mean you will be able to use the function. The

Experience Profile Anonymous, Unknown and Known contacts

When you first get started with Sitecore's experience profile the reporting for contacts can cause a little confusion. There are 3 terms that are thrown around, 1) Anonymous 2) Unknown 3) Known. When you read the docs they can bleed into each other a little. First, have a read through the Sitecore tracking documentation to get a feel for what Sitecore is trying to do. There are a couple key things here to first understand: Unless you call " IdentifyAs() " for request the contact is always anonymous.  Tracking of anonymous contacts is off by default.  Even if you call "IdentifyAs()" if you don't set facet values for the contact (like first name and email) the contact will still show up in your experience profile as "unknown" (because it has no facet data to display).  Enabled Anonymous contacts Notice in the picture I have two contacts marked in a red box. Those are my "known" contacts that I called "IdentifyAs"

Anatomy of Sitecore Business Rule - Macros

In previous posts, we talked about  field syntax and the basic structure of business rules . This time we are going to dive into macros in the business rules. Macros are used as part of the business rule syntax. The syntax looks like this and calls for 4 parameters. [Property to set, Operator/Macro, AdditionalParameters, Display text]. When I first started working with business rules the difference between operator and macro was confusing. To add to this confusion some of the out-of-the-box macros are named with the term "operator" (like ListOperator who's configuration points to a class called ListMacro and the class implements IRuleMacro). Anything under the path /sitecore/system/Settings/Rules/Definitions/Macros should be a macro and should implement IRuleMacro. Macros have the follow characteristics: They inherit the IRuleMacro interface The interface requires this execute method void Execute(XElement element, string name, UrlString parameters, string value)