This article covers a Bloomreach Experience Manager version 12. There's an updated version available that covers our most recent release.

Create a custom field validator

Validation only works for documents with workflow defined, i.e. of type hippostdpubwf:document

1. First you need to create a validator plugin.

This plugin should extend the  org.hippoecm.frontend.editor.validator.plugins.AbstractCmsValidator class.

An example is the  RegExCmsValidator plugin:

public class RegExCmsValidator extends AbstractCmsValidator {
    @SuppressWarnings({"UnusedDeclaration"})
    private static Logger log = LoggerFactory.getLogger(RegExCmsValidator.class);
    
    private final Pattern pattern;
   
    private final static String PATTERN_KEY = "regex_pattern";
   
    public RegExCmsValidator(IPluginContext context, IPluginConfig config)
                                                              throws Exception {
      super(context, config);
      if (config.containsKey(PATTERN_KEY)) {
       pattern = Pattern.compile(config.getString(PATTERN_KEY));
      }
      else
      {
       throw new Exception("regex_pattern property should be set in the iplugin
                                         configuration of: " + config.getName());
      }
    }
   
    @Override
    public void preValidation(IFieldValidator type) throws ValidationException {
      if (!"String".equals(type.getFieldType().getType())) {
      throw new ValidationException("Invalid validation exception; cannot
                                       validate non-string field for emptyness");
      }
    }
   
    @Override
    public Set<Violation> validate(IFieldValidator fieldValidator,
                                   JcrNodeModel model, IModel childModel)
                                                     throws ValidationException {
      Set<Violation> violations = new HashSet<Violation>();
      String value = (String) childModel.getObject();
      if (!pattern.matcher(value).find()) {
        violations.add(fieldValidator.newValueViolation(childModel, getTranslation()));
      }
      return violations;
    }
}

The API requires to implement the following methods:

  • preValidation: Used to check the field type; e.g. if the field is a String type field. (see above example).
  • validate: The method where you perform the check and return the violations. You can retrieve all kinds of information from the arguments e.g.;
    • String field value: (String) childmodel.getObject();
    • Compound type node:  ((JcrNodeModel) childModel).getNode()
    • Document node:  model.getNode();

2. Add the validator plugin to the frontend configuration.

To register the plugin add a new frontend:plugin to the cms-validators plugin cluster. Located at the the following path:

/hippo:configuration/hippo:frontend/cms/cms-validators

Example of the email validator:

3. Reference the validator from the nodetype (namespace)

Find the document type and the field in the hippo namespace which you'd like to validate. Example: 

'Email' field of the an 'author' document type:


Add the node name of the plugin (made in step 2) as a value to the hipposysedit:validator property.

4. I18n & API

The last step is to create the validation message. Validator messages are stored as repository resource bundles at:

/hippo:configuration/hippo:translations/hippo:cms/validators/

For each of the languages in your project, add a translation property with the same name as the plugin (made in  step 2) with the appropriate violation message to the resource bundle of the target language. Note that is it possible to define multiple violation messages for a plugin, in which case the property name is composed as "<plugin-name>#<subKey>" such as in the example below:

Note that you can access the translation from the API with the #getTranslation method and access alternate translations with the #getTranslation(String subKey) method

violations.add(fieldValidator.newValueViolation(childModel,
                                                getTranslation()));
...
violations.add(fieldValidator.newValueViolation(childModel,
                                                getTranslation(FORMNOTVALID)));

Check if your validator works:

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?