First read the doc about dynamic plugins (OSGI) and how to set up an OSGi plugin environment
An example Rules Engine OSGi Conditionlet Plugin can be found under /docs/examples/osgi/com.dotcms.ruleengine.conditionlet in the dotCMS release.
- The class that extends a rules engine Conditionlet is named:
com.dotmarketing.portlets.rules.conditionlet.Conditionlet
- Any custom conditionlet must:
- Provide a name / I18n Key and a list of ParameterDefinitions to the superclass constructor,
protected Conditionlet(String i18nKey, ParameterDefinition... parameterDefinitions)
- The Condition type should generally be fully configured at creation time. That is to say, when the constructor exits, the Condition should be 'fully defined'. While it is possible to override the
public Map<String, ParameterDefinition> getParameterDefinitions()
method in order to dynamically update the parameter definitions based on current system state, it is discouraged. Instead, consider using or create newInputElements
that define where and how to gather dynamic data. For an example, see the internal classcom.dotmarketing.portlets.rules.actionlet.PersonaActionlet
and its use of the REST-populated dropdown inputcom.dotmarketing.portlets.rules.parameter.display.RestDropdownInput
- The Condition type should generally be fully configured at creation time. That is to say, when the constructor exits, the Condition should be 'fully defined'. While it is possible to override the
- Implement the method
public Instance instanceFrom(Map<String, ParameterModel> parameters)
- In 'Instance' is a container for validated parameters. This method is called when an instance of your Condition is saved (e.g. when modified from the User Interface) as well as when shydrating data from the database. Expensive operations that can be performed in this method should be, as this method is called infrequently as compared to the
evaluate(...)
method.
- In 'Instance' is a container for validated parameters. This method is called when an instance of your Condition is saved (e.g. when modified from the User Interface) as well as when shydrating data from the database. Expensive operations that can be performed in this method should be, as this method is called infrequently as compared to the
- Implement the abstract method
public boolean evaluate(HttpServletRequest request, HttpServletResponse response, Instance instance)
- The evaluate method performs the check that forms the basis for the Condition. This can happen as frequently as multiple times per request to your active site, depending on number of rules and their configurations. The evaluate method is provided the Instance that was generated by
instanceFrom
, as well as the Request and Response objects. Care should be taken to avoid ambiguous return values, such as returningfalse
on error conditions that can occur when data is unavailable. - In the
UsersContinentConditionlet
example we use geoIp2Util to find the Country and Continent of the request and it returns true if the comparison + input is correct. If the users location is not available, we throw an exception, so as to avoid returning the same logical result for both the IS and IS_NOT comparisons. A more robust solution might be to add another input option of 'Unknown' for the continent and augment the 'getContinent logic accordingly. - Throwing expceptions frequently is discouragaged, as future implementations are likely to disable Rules that fail to evaluate after some configurable number of consecutive exceptions.
- The evaluate method performs the check that forms the basis for the Condition. This can happen as frequently as multiple times per request to your active site, depending on number of rules and their configurations. The evaluate method is provided the Instance that was generated by
- Provide a name / I18n Key and a list of ParameterDefinitions to the superclass constructor,
- Important classes:
ParameterDefinition [com.dotmarketing.portlets.rules.parameter.ParameterDefinition]
: A container for a user editable input paramater. Takes an I18N key (which is treated as a simple name if there are no '.' characters) and an instance of anInput
implementation.Input [com.dotmarketing.portlets.rules.parameter.display.Input]
: Defines the user view of a Parameter. For instance, simple text field, select (dropdown), date-time field and others. Also provides a location for configuring validations and user-input constraints, such as 'required', maximum values for number fields, maximum/minimum string lengths or custom validations.DataType
[com.dotmarketing.portlets.rules.parameter.type.DataType]: Enforces data-type constraints. Though similar to input constraints, DataType constraints should focus more on validating specific aspects of a datatype (e.g. a Date string), while instance of Input should accept validations that enforce specifics about a particular date (is before, is after).
- i18n: When you call the
registerRuleConditionlet
method in the Activator, it will scan your /resources/messages folder and it will include all the message properties for the existing languages in dotCMS.- The message file has to follow this naming standard: Language_xx-XX.properties, for example: Language_en-US.properties, Language_es-ES.properties, etc.
- Each message has to follow the following standard: Key=Value, for example: com.dotmarketing.osgi.ruleengine.conditionlet.name=User's Continent
- As a suggestion, instead of returning labels in your custom conditionlet, you can return keys that will then be used to query the i18n endpoint.
- Build using the command
./gradlew jar