Support and Documentation

Custom visibility labels

By implementing the VisibilityLabel interface, you can create custom states for content types. Implementations of this interface set custom labels on objects hidden by a visibility-indexed field. In Brightspot, the custom labels provide a query filter for retrieving the hidden objects.

The following example shows how to use visibility labels to set and display visitor comments on articles. In this scenario, visitors post comments on individual articles, and a site administrator approves or rejects the comment for publication.

To implement this comment-review scenario, a Comment class is used with a visibility-indexed field that stores the state of a comment, either in-review, rejected, or null. If null, the comment is published.

The visibility-indexed field takes a ModerationState enumeration, which has two constants, IN_REVIEW and REJECTED.

public enum ModerationState {

    IN_REVIEW("In Review"),

    private final String displayName;

    ModerationState(String displayName) {
        this.displayName = displayName;

    public String getDisplayName() {
        return displayName;

In the Comment class, a ModerationState constant is set on moderationState. The class also implements the createVisibilityLabel method from the VisibilityLabel interface.

public class Comment extends Content implements VisibilityLabel {

    private String text;
    private User author;
    private Article articleCommentedOn;

    @Indexed(visibility = true)
    private ModerationState moderationState;

    protected void afterCreate() {

        if (getState().isNew()) {
            moderationState = ModerationState.IN_REVIEW;

   public String createVisibilityLabel(ObjectField field) {
      if ("moderationState".equals(field.getInternalName())) {
         return moderationState != null ? moderationState.getDisplayName() : null;
      return null;   }

   /* Getters and setters */

  • Lines 3–9 declare Comment fields:

    • text stores a visitor's comment entered on the frontend.

    • author stores the visitor who enters the comment.

    • articleCommentedOn stores the article on which the comment is entered.

    • moderationState declares the visibility-indexed field. The @ToolUi.Placeholder annotation is applied to the field so that a third option, Approved, is available in the Brightspot content edit form. An administrator can set this option on the moderationState field, in addition to the ModerationState constants of IN_REVIEW and REJECTED. Selecting Approved in Brightspot sets the moderationState field to null, thus making the Comment object retrievable by queries and viewable on the frontend.

  • Lines 11–18 show the afterCreate method, triggered when a comment record is instantiated. The method sets moderationState to the IN-REVIEW value for a new comment.

  • Lines 20–26 implement the visibilityLabel#createVisibilityLabel method, which returns the value of the moderationState field. Because the Comment class has a visibility-indexed field, Brightspot automatically calls this method and passes the ObjectField for moderationState. The method returns a string label, reflecting the state of the object.

When a visitor enters a comment on the frontend, a Comment object is created in an in-review state. In the content edit form, an administrator can approve or reject the comment for publication.


The createVisibilityLabel method returns string labels to Brightspot, which uses the labels in the UI to reflect the state of an object. For example, if moderationState is set to IN_REVIEW or REJECTED, the createVisibilityLabel method returns the applicable ModerationState value to Brightspot. In the Revisions widget, past comments are identified by IN REVIEW or REJECTED. In the search panel, Brightspot adds the labels to the status filter for the Comment content type:


To find comments that have not been published, you can use the following queries:

/*Return a query for all comments in the review state. */
   return Query.from(Comment.class).where("moderationState = ?", ModerationState.IN_REVIEW);

/* Return a query for all rejected comments for a specified visitor */
   return Query.from(Comment.class)
               .where("moderationState = ?", ModerationState.REJECTED)
               .and("author = ?", author);