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 Field

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:

public class Article extends Content {

    private String title;

}

You can place annotations on text fields. For example:

public class Article extends Content {

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

}
../../../_images/annotations-on-fields.png

Rich Text

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.

../../../_images/rich-text-editor.png

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.

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 Field

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;

}
../../../_images/new-author.png

Next, include the author class inside the article 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.

../../../_images/content-picker.png

Date Widget

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.

public class Article extends Content {

    private Date dateWidget;

}
../../../_images/date-widget.png

Boolean Field

A Boolean field renders a checkbox on the Model’s Content Edit Form. For example, you can add a checkbox to auto-play a video.

public class Video extends Content {

    private boolean autoplay;

}
../../../_images/boolean-widget.png

Enum Field

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.

public class Show extends Content {

    private Day airtime;

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

}
../../../_images/enum-widget.png

List Fields

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.

public class Article extends Content {

    private List<Author> authors;

}
../../../_images/list-widget.png

Set Fields

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

public class Article extends Content {

    private String title;
    private Set<Author> authors;
}

Storage Item

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

public class Article extends Content {

    private StorageItem image;

}
../../../_images/storage-widget.png

Location

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 ViewModel.

Step 1: Add Location to Model

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package content.article;

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;
    }

}

In the previous snippet, line 8 adds a location field to the Model. For fields and methods available with this field, 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.

../../../_images/location-initial.png

Step 2: Add Location to Handlebars File

The Handlebars file 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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<!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>

In the previous snippet—

  • Lines 5–6 provide access to the Leaflet API.
  • Line 10 provides the required <div> container for a Leaflet map.
  • Lines 11–19 provide the required JavaScript for displaying the map and marker.
    • Line 12 includes the Handlebars placeholder for the marker’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.)
    • Line 18 includes the Handlebars placeholder for the marker’s location on the map.

Step 3: Add Location to JSON File

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

1
2
3
4
{
    "_template": "Article.hbs",
    "locationCoords": "40.6892, -74.0445"
}

In the previous snippet, line 3 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.

1
2
3
{
   "_include": "content/article/Article.json"
}

Step 5: Implement Location Field in ViewModel

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
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;
    }

}

In the previous snippet—

  • Lines 10–15 override the View’s getLocationCoords method, which itself is sourced in the JSON file from Step 3.
  • Line 13 retrieves the x- and y-coordinates, and assembles them into a string as expected by the Leaflet API.

Region

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 ViewModel.

Step 1: Add Region to Model

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
package content.article;

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;
    }

}

In the previous snippet, line 8 adds a region field to the Model. For fields and methods available with this field, 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 Handlebars File

The Handlebars file 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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<!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>

In the previous snippet—

  • Lines 5–6 provide access to the Leaflet API.
  • Line 10 provides the required <div> container for a Leaflet map.
  • Lines 12–18 provide the required JavaScript for displaying the map and region.
    • Line 15 includes the Handlebars placeholder for the region’s coordinates.
    • Line 16 adds the coordinates to the map.
    • Line 17 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.

1
2
3
4
{
    "_template": "Article.hbs",
     "regionCoords": "[[[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]]]"
}

In the previous snippet, line 3 provides static vertices for the regionCoords placeholder.

Step 4: Include the JSON File in a Wrapper

Include Article.json in styleguide/_wrapper.json.

1
2
3
{
   "_include": "/path/Article.json"
}

Step 5: Implement Region Field in ViewModel

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

 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
31
32
33
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.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();
    }

}

In the previous snippet—

  • Lines 11–31 override the View’s getRegionCoords method, which itself is sourced in the JSON file from Step 3.
  • Line 14 declares a vector that holds an arbitrary number of coordinates as strings.
  • Line 17 retrieves all the field’s polygons as a list.
  • Line 18 retrieves the first polygon in the list.
  • Lines 20—26 loop through the polygon’s vertices, retrieving the x- and y-coordinates, and adding them to the vector of coordinates.
  • Lines 28—30 join the coordinates into a single string surrounded by brackets, and return that string to the View.

Markdown Editor

You can use a Markdown editor instead of Rich Text, if needed.

public class Documentation extends Content {

    private String name;
    private Markdown markdownText;

    // Getters and Setters
}
../../../_images/markdown-widget.png

Embedded Types

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; whenever a user creates or modifies an article, the author’s fields are exposed.

public class Article extends Content {

    private String title;
    @Embedded
    private Author author;

    // Getters and Setters
}
../../../_images/field-level-embed.png

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
public class Author extends Content {

    private String name;

    // Getters and Setters
}

Query Field

Like any Record-derived class, Query can be used as a field in a Model. A Query field allows editors to use the Query UI in Brightspot to set an SQL query in the Model.

The Article example includes a Query field.

public class Article extends Content {

   @Required
   @Indexed
   private String headline;

   @ToolUi.RichText
   @Indexed
   private String body;

   private Query query;

    // getters/setters
}

When an Article is created in Brightspot, the Query field appears in the content edit form.

../../../_images/query-article.png

Clicking search in the Query selection field displays the content picker, from which an editor can create a new query or select an existing one, if any.

../../../_images/content-picker-query.png

Clicking New Query displays the New Query UI, which includes the standard search fields and shows the results of the query as it is constructed. The following screenshot shows the results of setting the content type filter to Article. Predicates can be added to the query with Advanced Query Search.

../../../_images/new-query-ui.png