Optimizely Content Management System (CMS) comes with a number of predefined visitor group criteria but you can develop your own.
Each criterion defines a condition which is evaluated to determine if a visitor is part of a group. If a sufficient number of visitor group criteria are fulfilled, the visitor is considered a member of that group. The following example shows a **Time of Day** criterion that is fulfilled if the current time is between 8 AM and 12 PM, except on weekends:
From a development standpoint, a visitor group criterion is a combination of (at least) two classes:
A _model class_, which stores and persists user input from the user interface.
A _criterion class_, which evaluates the context and the data stored in the model to determine if the criteria are fulfilled.
Make sure that your project references and the following assemblies contain the classes you need to create criteria and models.
## DojoWidget property attribute
If you want to use [another Dojo widget than default](🔗), you can control that by decorating the properties on your model class with the `
DojoWidget` attribute. You also can use that attribute to set things like default value and where to find translations for the label. If you want even more control over the user interface, create your own [Editor templates](🔗) or write a Custom Script as shown.
If you want the input for a value to be a drop-down list with predefined options, set `
SelectionFactoryType` on the `
DojoWidget` attribute. The `
SelectionFactoryType` is a type that implements `
ISelectionFactory`. The `
ISelectionFactory` has a `
GetSelectListItems` method that is responsible for supplying options for the drop-down list.
You can use an `
EnumSelectionFactory` included in the CMS to present the options of an `
Enum` in a drop-down list. When you use `
EnumSelectionFactory`, provide translations of the `
Enum` values and place the translated values in your own XML file in the _/lang_ directory. See Enumeration Localization in [Localizing the visitor group criterion](🔗).
## Validate the server side
You can add input validation to your properties by using the attribute classes in `
System.ComponentModel.DataAnnotations`. The following validation rules are supported:
[Range(double Minimum, double maximum)]`
If you want to add custom server side validation, you can implement the interface `
IValidateCriterionModel` on your model. The `
IValidateCriterionModel` supplies a `
Validate` method that is called when you save a visitor group containing the criterion.
## Create a criterion class
After you have a model class, create the criterion class to evaluate the context and the data stored in the model, to determine if the criteria is fulfilled or not. The connection between the criterion and model classes is created via `
CriterionBase` – the base class that you must use for the criterion class – which is a generic class that accepts `
ICriterionModel` parameters. You must override the `
CriterionBase.IsMatch` method, which is the central method for a criterion; it is called when evaluating if a user is a member of a visitor group.
Decorate the criterion class with `
VisitorGroupCriterion` attribute, which identifies your class as a criterion and makes it available for use. `
VisitorGroupCriterion` has the following settings:
Category` – The name of group in the criteria picker user interface where this criterion is located. Criteria with the same `
Category` value are grouped together.
Description` – A text describing how the criterion works.
DisplayName` – A short name that identifies the criterion in menus and visitor groups.
LanguagePath` – The path in the XML language files where the strings associated with this criterion is located. See [Localizing the visitor group criterion](🔗).
## Subscribe to events
You can subscribe to specific events by overriding the `
Subscribe` method, which gathers information about events that occur prior to the call to the `
IsMatch` method. For example, the built-in Visited Page criterion needs to keep track of all pages that are visited in the current session. You can subscribe to the following events:
If you override the `
Subscribe` method and attach event handlers, make sure that you also override the `
Unsubscribe` method and detach the event handlers.