Editorial content types, developer tab
With editorial content types, editors can create their own content types in Brightspot without having to rely on back-end data modeling; however, developers can assist in this process by adding more complex code that layers in unique business logic. The fields described below are in-CMS counterparts to the same features available in when defining a Content Type in Java, and exist to provide developers an additional way to configure editorial content types.


Each editorial content type, as well as each field defined on the content type, has a Developer tab with a number of developer-centric fields. Those fields are described in detail below:
Internal Name
Sets the Internal Name of the Content Type as well as drives the generated Java class name. If left unchanged, its value is derived from the Name field on the Main tab, normalized to follow the Java class naming conventions.
The value must be unique across all content types in the system, both editorial- and Java-based. As such, a typical reason to modify this field is to resolve conflicts with other similarly named Content Types.
Superclass
Sets the superclass of the Java class generated from this Content Type. The fully qualified class name provided must extend Record or some subclass thereof. The default value is set to Content, which will make the content type accessible within the CMS. If the superclass is set to something other than Content (or a subclass thereof), the content type will only be available via API.
A class / type hierarchy can be established by setting the value to the class name of another content type. If referencing another editorial content type, the class name will be the same as its Internal Name.
Renderer
Specifies how published content of this type is rendered when accessed via the permalinks set in the URLs Widget. A Renderer is an abstract content type and thus can be extended to provide custom implementations. All implementations will automatically show up in the field's drop down list. There are two implementations provided out of the box, Handlebars File and Handlebars Template.
Handlebars File
Accepts a path to a Handlebars template that will get loaded with the content being rendered in context. The template will have direct access to all of the field defined on this Content Type.
Handlebars Template
Accepts Handlebars template syntax as input with the content being rendered in context. The template will have direct access to all of the fields defined on this Content Type.
Interfaces
Sets the interfaces of the Java class generated from this Content Type. The class names must be fully qualified and exist in the running environment. If an interface has required methods, implementations must go in the Methods field.
Dynamic Note - Class level
Adds a class level dynamic note to instances of this Content Type. The field accepts JS code (executed using GraalVM) with a return statement at the end containing the desired note value. There is a variable named record
that is present in the JS context which holds the instance of the Content Type while it is being edited. It can be used to access the real time State of the Content in order to power the dynamic note, for example:
return record.getState().get("field")
Annotations - Type level
Allows modification of the underlying Object Type metadata for this Content Type. In Java, this is done indirectly via annotations. Here, the Object Type metadata can be modified directly with JS code (executed using GraalVM) by accessing the type
variable that is present in the JS context, which contains a reference to the ObjectType
backing this Content Type, for example:
type.as(Java.type('com.psddev.cms.db.ToolUi')).setReadOnly(true)
Methods
Adds methods to the Java class generated from this Content Type. The field accepts JS code (executed using GraalVM) where each declared function is converted into a corresponding Java method on the generated class. Used primarily to implement or override abstract or interface methods defined by the Superclass and Interfaces fields, for example:
function method1() {
}
function method2(argument) {
}
Internal Name - Field level
Sets the Internal Name of the Content Type Field as well drives the generated Java field name. If left unchanged, its value is derived from the Name field on the Main tab, normalized to follow the Java class naming conventions.
The value must be unique across all fields of this Content Type, but Brightspot will attempt to resolve conflicts automatically, so there is little need to modify this field manually.
Dynamic Note - Field level
Adds a field level dynamic note to this Content Field. The field accepts JS code (executed using GraalVM) with a return statement at the end containing the desired note value. There is a variable named record
that is present in the JS context which holds the instance of the Content Type while it is being edited. It can be used to access the real time State of the Content in order to power the dynamic note. In addition, there is a variable named field
which hold a reference to the ObjectField
backing this Content Field, e.g.
return field.getInternalName()
Dynamic Placeholder
Adds a field-level dynamic placeholder to this Content Field. The field accepts JS code (executed using GraalVM) with a return statement at the end containing the desired placeholder value. There is a variable named record
that is present in the JS context which holds the instance of the Content Type while it is being edited. It can be used to access the real time State of the Content in order to power the dynamic placeholder, e.g.
return record.getState().get('anotherField')
Annotations - Field-level
Allows modification of the underlying Object Field metadata for this Content Field. In Java, this is done indirectly via annotations. Here, the Object Field metadata can be modified directly with JS code (executed using GraalVM) by accessing the field
variable that is present in the JS context, which contains a reference to the ObjectField
backing this Content Field, for example:
field.as(Java.type('com.psddev.cms.db.ToolUi')).setReadOnly(true)