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"),
REJECTED("Rejected");
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class Comment extends Content implements VisibilityLabel {
private String text;
private User author;
private Article articleCommentedOn;
@Indexed(visibility = true)
@ToolUi.Placeholder("Approved")
private ModerationState moderationState;
@Override
protected void afterCreate() {
super.afterCreate();
if (getState().isNew()) {
moderationState = ModerationState.IN_REVIEW;
}
}
@Override
public String createVisibilityLabel(ObjectField field) {
if ("moderationState".equals(field.getInternalName())) {
return moderationState != null ? moderationState.getDisplayName() : null;
}
return null;
}
/* getters and setters */
}
|
In the previous snippet—
- Lines 3–9 declare
Comment
properties: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 content edit form. An administrator can set this option on themoderationState
field, in addition to theModerationState
constants ofIN_REVIEW
andREJECTED
. Selecting Approved in Brightspot sets themoderationState
field tonull
, thus making theComment
object retrievable by queries and viewable on the frontend.
- Lines 11–18 show the
afterCreate
method, triggered when a comment object is instantiated. The method setsmoderationState
to theIN_REVIEW
value for a new comment. - Lines 20–26 implement the
visibilityLabel#createVisibilityLabel
method, which returns the value of themoderationState
field. Because theComment
class has a visibility-indexed field, Brightspot automatically calls this method and passes the ObjectField formoderationState
. 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);