Personalize Content with Sitefinity

April 03, 2017 Digital Experience, Sitefinity

Serving content to your audience is hard when you have different groups of people to target. For those cases generic content or long articles targeting everyone are not a good option. The simplest solution is to use personalized articles and pages. In the context of Sitefinity, this is an easy job.

How to Personalize with Sitefinity?

To target a specific group of people you need to create a personalized user segment. The Sitefinity CMS lets you choose from a predefined set of rules to apply. Once the segment is created, the content associated with it will be shown when the users meet the criteria, e.g. if they live in Raleigh, NC. 

When a page is personalized, you choose which segment to apply to the specific version—and you can switch between them easily. 

On the page surface, place the layouts and controls suitable to your target group. When you want to personalize specific widgets rather than the whole page, you can do this out of the box for the following: Content block, Image and Card. With this approach, you will be able to fine tune everything easily.

How to Create Custom Criteria to Meet My Requirements?

The above approaches are enough to complete the straightforward cases, but there are many other requirements and conditions beyond the usual scenarios. To cover them you have to implement custom criteria and then apply them to widgets and pages through segments.

The example that I am going to analyze resides in the Sitefinity documentation, and covers everything from how to create custom criteria to how to apply them programmatically to a page. Please follow the steps from the help and create a separate project from it because we will discuss different parts of the code and how they work below.

The most important part of the sample is the creation of the criteria. Its implementation is split into two main parts—server and client and how to pass values between them.

The server class should implement the ICriterionEvaluator interface. The logic in the IsMatch method decides whether to show the personalized content or the default one.
public bool IsMatch(string settings, IPersonalizationTestContext testContext)
{
    if (settings == this.CurrentDayOfWeek.ToString())
    {
        return true;
    }
    else
    {
        return false;
    }
}

 

The next step is to analyze the client view and understand how to pass values to the server. The first requirement is to define a class with a specific name in your JavaScript—CriterionEditor. If another name is used the criteria client view will not work, so it is important to follow the code guidelines. The class prototype should be extended with specific methods which the system is going to look for: getCriterionTitle, getCriterionDisplayValue, getCriterionValue, setCriterionValue, errorMessage and isValid.

function CriterionEditor() {
 
}
 
 
CriterionEditor.prototype = {
    //Used as a label for the criterion when viewing the user segment
    getCriterionTitle: function () {
        return "{$CustomPersonalizationResources, Day$}";
    },
 
    //The descriptive value for the criterion
    getCriterionDisplayValue: function () {
        return $("#day option:selected").text();
    },
 
    //Persists the input from the user as a value for the criterion
    getCriterionValue: function () {
        return $("#day").val();
    },
 
    //When the editor opens, sets the previously persisted value
    //as initial value for the criterion
    setCriterionValue: function (val) {
        $("#day").val(val);
    },
 
    errorMessage: "",
 
    isValid: function () {
        var day = $("#day").val();
        if (day.length === 0) {
            this.errorMessage = "{$CustomPersonalizationResources, DayError$}";
            return false;
        }
        return true;
    }
};

 

Following the guidelines and the code sample, this should be the visual result in your Backend—only one dropdown:

The next step is to pass the value of the selected item from the dropdown to the server. The returned value from the getCriterionValue function is passed to the IsMatch sever method in the settings overload parameter.

Once you have the criterion skeleton it should be registered in the system. From the Installer class the AddVirtualPathToEmbeddedRes(), CreateCriteria() and RegisterCriteria() methods are doing that magic. The rest of the methods in the Installer class are creating a page for you.

How to Personalize Custom Widgets?

The other part of the puzzle is how to apply personalization to custom widgets. Mark the controller class with the IPersonalizable interface and your widget will be powered up with the personalization option.

[ControllerToolboxItem(Name = "HelloWorldWidget", Title = "HelloWorld Widget", SectionName = "CustomMVCWidgets")]
    public class HelloWorldController : Controller, IPersonalizable
    {
        public string Message { get; set; }
 
        // GET: HelloWorld
        public ActionResult Index()
        {
            var model = new HelloWorldModel();
            model.Message = Message;
            return View(model);
        }
    }

 

How to Personalize Existing Widgets?

Only three widgets support personalization out of the box. For the rest of them you have to inherit and extend the base implementation by marking it with the IPersonalizable interface.

[ControllerToolboxItem(Name = "PersonlizedNews", Title = "Personlized News", SectionName = "CustomMVCWidgets")]
public class PersonalizedNewsController : NewsController, IPersonalizable
{
    
}

Once you inherit the class, don’t forget to copy and paste the widget’s view files in the View folder.

Know Your Audience and Serve the Best Content for Them

Sometimes personalization becomes a complex affair because of the different preferences of your customers, but with Sitefinity you can streamline the whole process. Understand your customers’ needs and customize every page and detail to reach them best. For your convenience Progress Sitefinity team provides sandbox instances where you could start testing your ideas. 

Peter Filipov

Peter Filipov (Pepi) is a Product Builder focused on building the future of Sitefinity, relying on the newest technologies such as .NET 6 (and up), React and Angular. His previous experience as a Developer Advocate and Manager of Engineering helps him to understand the customers’ and market needs of Sitefinity. He also is passionate about being active and healthy.

Read next 3 Ways to Boost Digital Marketing Maturity