Brightspot CMS Developer Guide

Field types

This section describes the field types you can add to your model classes. As you develop your Brightspot project, you can extend classes that contain any combination of these field types.

Text fields are the simplest field type. These fields provide a text input for users like a title, basic input, or a small body of text without rich-text formatting.

To add a text field, add a String to the class within which the text field will exist.

For example, to add a title text field to an Article class:

Field types text field
public class Article extends Content {

    private String title;

}

You can place annotations on text fields. For example:

Field types text field 2
public class Article extends Content {

    @ToolUi.Note("Editorial Note")
    private String withEditorialNote;

    @Required
    private String requiredExample;
}

Rich text is a combination of plain text, formatting, and embedded objects such as images and videos. Authors often use rich text to emphasize words or ideas.

Brightspot’s rich-text formatting features are available in the rich-text editor. The editor has a toolbar and an editing area.

Rich-text editors output formatted text with HTML tags, such as <b> and <a> .

To display the rich-text editor in the Content Edit Form, apply the @ToolUi.RichText annotation to a String field. Without any elements, this annotation presents the default rich-text toolbar.

To display the rich-text editor in the content edit form, apply the @ToolUi.RichText annotation to a String field. Without any elements, this annotation presents the default rich-text toolbar.

Activating a rich-text field
public class Article extends Content {

    @ToolUi.RichText
    private String body;

}

See also:

  • For elements available with the @ToolUi.RichText annotation, see @ToolUi.RichText . In particular, you can use this annotation to display different rich-text toolbars with different fields.
  • For detailed information about customizing the rich text feature, including the toolbar, preconfigured rich-text elements, and rendering rich text, see Rich text .
  • For information about annotations that customize the rich-text feature at the class level, see @RichTextElement.Tag .
  • For information about annotations that customize the rich-text feature at the field level, see @RichTextElement.Tags .

Object fields are controls for displaying a list of existing objects or for creating a new object of a specified class. For example, to implement a list of existing authors in each article object, first create a class for authors.

Example of child class
public class Author extends Content {

    private String lastName;

    private String firstName;

}

Next, include the author class inside the article class.

Object field author class
public class Article extends Content {

    private String headline;

    private String body;

    private Author author;

}

Users can click on the author field to select from a list of existing authors or to create a new author.

The Date widget allows you to choose a specific date from a calendar drop-down menu. With the Date widget, you can specify a publish date for a piece of content, a blog post, or news article, for example.

To implement the Date widget as a field, add private Date to the model.

Date widget
public class Article extends Content {

    private Date dateTaken;

}

A Boolean field renders a toggle on the model’s content edit form. For example, you can add a checkbox to auto-play a video.

Boolean field
public class Video extends Content {

    private boolean autoplay;

}

Enum field types are drop-down menus with a predetermined list of options. For example, an enum field can list the possible days on which a program airs.

To add an enum field, add a public enum property to the class and specify the options.

Enum field
public class Show extends Content {

    private Day airtime;

    public enum Day {
        SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
    }

}

List fields allow you to create a list that pulls from existing content within Brightspot. For example, if your content needs a list of contributing authors, you can add a List field referencing only Author objects. If a desired author name doesn’t exist, you can create a new author in the field search widget.

Once you’ve created a list of items, you can drag the items on the list to re-order them.

This field can be implemented into a model by adding private List <author> authors.

Set Fields are similar to List Fields, but items in a Set cannot be reordered. You can implement Set Fields like List Fields.

Set fields
public class Article extends Content {

    private String title;
    private Set<Author> authors;

}

StorageItems allow files to be uploaded and stored in the default storage mechanism defined in the context.xml .

StorageItem field
public class Article extends Content {

    private StorageItem image;

}

A Location object stores a latitude-longitude coordinate. When you add a location field to a model, Brightspot displays a map in the content edit form with a marker. A user positions, pans, and zooms in the field until the marker is at the required location and magnification. When the user saves the content edit form, Brightspot retains the marker’s final coordinates (but not the final zoom).

To render a map with a marker at the stored location, you need to integrate a mapping service. Brightspot uses Open Street Map and Leaflet in the content edit form.

The following steps outline how to implement location objects in a model, view, and view model.

Step 1: Add location to model

Under your project’s src/main/java/content/article/ directory, save the following in a file Article.java.

Add location to model
import com.psddev.cms.db.Content;
import com.psddev.dari.db.Location;

public class Article extends Content {

    private Location location; 

    public void setLocation(Location location) {
        this.location = location;
    }

    public Location getLocation() {
        return location;
    }

}
  • Adds a Location field to the model. For fields and methods available with this class, see Class Location.

When a user creates a new asset with a location field, the content edit form initializes the location field to a display of the continental United States with a marker in the center.

Step 2: Add location to template

The template needs to include the location as well as a third-party mapping service. The following snippet uses Leaflet.

Under your project’s styleguide/content/article/ directory, save the following in a file Article.hbs.

Add location to template
<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin=""/> 
        <script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet.js" integrity="sha512-A7vV8IFfih/D732iSSKi20u/ooOfj/AGehOKq0f4vLT1Zr2Y+RX7C+w8A1gaSasGtRUZpF/NZgzSAu4/Gc41Lg==" crossorigin=""></script>
    </head>

    <body>
        <div id="mapid" style="height:580px;"></div> 
        <script> 
            var mymap = L.map('mapid').setView([{{locationCoords}}], 12); 

            L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
                id: 'mapbox.streets'
            }).addTo(mymap);

            L.marker([{{locationCoords}}]).addTo(mymap); 
        </script>
    </body>
</html>
  • Provides access to the Leaflet API.
  • Provides the required
    container for a Leaflet map.
  • JavaScript for displaying the map and marker.
  • Instantiates a map. The placeholder {{locationCoords}} is populated with the location’s coordinates, and the map is centered on those coordinates. (The 12 in this line represents the zoom level, a value that is not available in the Location class. You may want to implement the zoom level as a static field in your model.)
  • Adds the location marker to the map at the coordinates provided by the placeholder {{locationCoords}}.

Step 3: Add location to JSON file

Under your project’s styleguide/content/article/ directory, save the following in a file Article.json.

Add location to JSON file
{
    "_template": "Article.hbs",
    "locationCoords": "40.6892, -74.0445" 
}
  • Provides static coordinates for the {{locationCoords}} placeholder.

Step 4: Include the JSON file in a wrapper

Under your project’s styleguide/ directory, save the following in a file _wrapper.json.

Include the JSON file in a wrapper
{
   "_include": "content/article/Article.json"
}

Step 5: Implement location field in view model

Under your project’s src/main/java/content/article/ directory, save the following in a file ArticleViewModel.java.

Implement location field in view model
package content.article;

import com.psddev.cms.view.ViewModel;
import com.psddev.cms.view.PageEntryView;
import styleguide.content.article.ArticleView;
import com.psddev.dari.db.Location;

public class ArticleViewModel extends ViewModel<Article> implements ArticleView, PageEntryView {

    @Override 
    public String getLocationCoords() {
        Location location = model.getLocation();
        String locationCoords = location.getX() + ", " + location.getY(); 
        return locationCoords;
    }

}
  • Overrides the view’s getLocationCoords method, which itself is sourced in the JSON file from Step 3.
  • Retrieves the x- and y-coordinates, and assembles them into a string as expected by the Leaflet API.

A Region object stores a list of latitude-longitude coordinates (in the case of a polygon) or a coordinate-radius pair (in the case of a circle). Brightspot displays regions in the content edit form as a map with polygons or circles. A user draws regions using standard pan, zoom, point, click, and drag actions inside the region field. When the user saves the content edit form, Brightspot retains the regions’ final coordinates (but not the final zoom).

To render a map with regions you need to integrate a mapping service. Brightspot uses Open Street Map and Leaflet in the content edit form.

The following steps outline how to implement region objects in a model, view, and view model.

Step 1: Add region to model

Under your project’s src/main/java/content/article/ directory, save the following in a file Article.java.

Add region to model
import com.psddev.cms.db.Content;
import com.psddev.dari.db.Region;

public class Article extends Content {

    private Region region; 

    public void setRegion(Region region) {
        this.region = region;
    }

    public Region getRegion() {
        return region;
    }

}
  • Adds a region field to the model. For fields and methods available with Region objects, see Class Region. This class has several nested classes for working with circles and polygons.

When a user creates a new asset with a region field, the content edit form initializes the region field to a display of the continental United States.

Step 2: Add region to template

The template needs to include the region as well as a third-party mapping service. The following snippet uses Leaflet.

Under your project’s styleguide/content/article/ directory, save the following in a file Article.hbs.

Add region to template
<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" type="text/css" href="/styleguide/All.min.css"> 
        <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin=""/>
        <script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet.js" integrity="sha512-A7vV8IFfih/D732iSSKi20u/ooOfj/AGehOKq0f4vLT1Zr2Y+RX7C+w8A1gaSasGtRUZpF/NZgzSAu4/Gc41Lg==" crossorigin=""></script>
    </head>

    <body>
        <div id="mapid" style="height:580px;"></div> 
        <script> 
            var map = L.map('mapid'); 
            L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' }).addTo(map);
            var latlngs = {{regionCoords}};  
            var polygon = L.polygon(latlngs, {color: 'red'}).addTo(map); 
            map.fitBounds(polygon.getBounds()); 
        </script>
    </body>
</html>
  • Provides access to the Leaflet API.
  • Provides the required
    container for a Leaflet map.
  • JavaScript for displaying the map and region’s border.
  • JavaScript for displaying the map and region’s border.
  • Retrieves the series of vertices from the placeholder {{regionCoords}}.
  • Instantiates a polygon using the retrieved series of vertices.
  • Zooms the map so that it fits the polygon.

Step 3: Add region to JSON file

Under your project’s styleguide/content/article/ directory, save the following in a file Article.json.

Add region to JSON file
{
  "_template": "Article.hbs",
  "regionCoords": "[[[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]]]" 
}
  • Provides static vertices for the {{regionCoords}} placeholder.

Step 4: Include the JSON file in a wrapper

Include Article.json in styleguide/_wrapper.json.

Include the JSON file in a wrapper
{
  "_include": "/path/Article.json"
}

Step 5: Implement region field in view model

Under your project’s src/main/java/content/article directory, save the following in a file ArticleViewModel.java.

Implement region field in view model
import com.psddev.cms.view.ViewModel;
import com.psddev.cms.view.PageEntryView;
import styleguide.content.article.ArticleView;
import com.psddev.dari.db.Region;
import java.util.Vector;

public class ArticleViewModel extends ViewModel<Article> implements ArticleView, PageEntryView {

    @Override 
    public String getRegionCoords() { 

        Vector<String> coordinatesList = new Vector<>(); 

        Region region = model.getRegion();
        Region.MultiPolygon multiPolygon = region.getPolygons(); 
        Region.Polygon polygon = multiPolygon.get(0); 

        for (Region.LinearRing ring : polygon) { 
            for (Region.Coordinate coordinate : ring) {
                String coordinateString = "[" + coordinate.getLatitude().toString() + ", " +      coordinate.getLongitude() + "]";
                coordinatesList.add(coordinateString);
            }

        }

        String joinedCoordinates = String.join(",", coordinatesList); 
        String polygonCoordinates = "[" + joinedCoordinates + "]";
        return polygonCoordinates.toString();
    }

}
  • Overrides the view’s getRegionCoords method, which itself is sourced in the JSON file from Step 3.
  • Declares a vector that holds an arbitrary number of coordinates as strings.
  • Retrieves all the field’s polygons as a list.
  • Retrieves all the field’s polygons as a list.
  • Loops through the polygon’s vertices, retrieving the x- and y-coordinates, and adding them to the vector of coordinates.
  • Loops through the polygon’s vertices, retrieving the x- and y-coordinates, and adding them to the vector of coordinates.

You can use a markdown editor instead of rich text, if needed.

Markdown editor
public class Documentation extends Content {

    private Markdown markdownText;

}

Embedding exposes a content type’s fields within another content type. There are two levels of embedding—at the field level and at the class level.

Embedding at the field level

At the field level, embedding exposes a class’s fields within the enclosing content type. In the following example, the Author class is embedded at the field level within the Article class; when an editor creates or modifies an article, the author’s fields are exposed.

Embedded types
public class Article extends Content {

    @Embedded
    private Author author;

}

Embedding at the class level

At the class level, embedding exposes the fields within any enclosing content type. In the following example, the Author class is embedded at the class level. Whenever you create a class that includes Author, the author’s fields are always exposed.

Embedded types at the class level
@Embedded
public class Author extends Content {

    private String name;

}

A Query field renders a content picker for composing a query.

Query field
import com.psddev.cms.db.Content;
import com.psddev.dari.db.Query;

public class QueryArticle extends Content {

   @Embedded
   private Query query; 

}
  • Renders a content picker for composing a query. The annotation @Embedded is required.

Selecting Set in the Query selection field and then clicking the pencil icon displays the content picker in which editors design a query.

Brightspot executes the query at run time, and the results appear on the front end.

Secret fields allows secure storage of text data in the default secure storage mechanism defined in the context.xml .

Secure secrets example
import com.psddev.cms.secret.Secret;

public class AcmeApiServiceSettings extends Content {

    @DisplayName("API Key")
    @Required
    private Secret apiKey;

}

For more information, see Secure secrets .