Rich text elements
Brightspot’s rich-text editor accommodates custom rich-text elements, such as embedded videos, image galleries, or pull quotes. For example, the following illustration is an example of a rich-text element rendered as a pull quote. The element contains typeface, alignment, and a left border.
The following steps outline how to design rich-text elements and attach them to the rich-text editor’s toolbar. Although the steps are specific to pull quotes, you can apply them to any custom rich-text element.
Step 1: Extend a rich-text element
All custom rich-text elements extend from RichTextElement .
import com.psddev.cms.db.RichTextElement;
import com.psddev.dari.db.Recordable;
import com.psddev.dari.util.StringUtils;
@Recordable.DisplayName("Pull Quote") 1
@RichTextElement.Tag( 2
value = "quote",
preview = true,
block = false,
root = true,
menu = "Enhancement")
public class PullQuoteRichTextElement extends RichTextElement {
@Required
private String quote;
public String getQuote() {
return quote;
}
public void setQuote(String quote) {
this.quote = quote;
}
@Override 3
public Map<String, String> toAttributes() {
return null;
}
@Override
public void fromAttributes(Map<String, String> attributes) {
}
@Override
public void fromBody(String body) {
setQuote(StringUtils.unescapeHtml(body));
}
@Override
public String toBody() {
return getQuote();
}
}
-
Specifies the rich-text element displays as a pull quote in the rich-text toolbar.
-
Specifies the presentation aspects of the rich-text element:
- The theme’s data files use the
value
element for creating the view. In this snippet, the data files must provision the rich-text element using the identifierquote
. - In the toolbar, the rich-text element appears under the menu item Enhancement.
@RichTextElement.Tag
annotation see @RichTextElement.Tag. - The theme’s data files use the
-
Overrides the methods
toAttributes
,fromAttributes
,fromBody
, andtoBody
. These methods provide the interface between the rich-text element and the associated editing widget. For details see Editing lifecycle of rich-text elements.
Step 2: Attach rich-text element to toolbar
import com.psddev.cms.rte.RichTextToolbar;
import com.psddev.cms.rte.RichTextToolbarItem;
import com.psddev.cms.rte.RichTextToolbarStyle;
public class CustomRichTextToolbar implements RichTextToolbar {
@Override
public List<RichTextToolbarItem> getItems() { 1
return Arrays.asList(
RichTextToolbarStyle.BOLD,
RichTextToolbarStyle.ITALIC,
RichTextToolbarStyle.UNDERLINE
RichTextToolbarStyle.ELEMENTS);
}
}
-
Attaches all custom rich-text elements to the toolbar.
Step 3: Create theme files
Under your project’s
styleguide
/ directory, create files for each field appearing in the rich-text element. For example, if a field
body
is typed as a rich-text field, then the theme’s files must provide the template, data file, and styling for the field
body
. As a best practice, ensure each file’s path and base name correspond to the rich-text element’s class. The following example provides an illustration for theme files corresponding to the class
PullQuoteRichTextElement
developed in Step 1.
./
└── <root>
├── src |
└── main |
└── java |
└── brightspot |
└── content |
└── article |
└── PullQuoteRichTextElement.java
└── styleguide
└── content
└── article
├── PullQuoteRichTextElement.hbs
├── PullQuoteRichTextElement.json
└── PullQuoteRichTextElement.less
For information about creating theming files, see Theme guide .
See also:
- Rendering rich text
- Rich-text toolbar
Subclasses of RichTextElement can implement the callbacks required for editing rich-text elements.
Inside the rich-text editor, clicking Edit fires two callbacks:
-
RichTextElement#fromBody
to populate the editing widget’s Link Text field and the Main tab of the Link field. -
RichTextElement#fromAttributes
to populate the editing widget’s Attributes field in the Advanced tab.
-
Inside the editing widget, clicking Save & Close fires two callbacks to create a traditional HTML link of the form
<a href="value” otherattribute="othervalue">link text</a>
:-
RichTextElement#toBody
to retrieve the link text from the editing widget’s Link Text field. -
RichTextElement#toAttributes
to retrieve the link’s attributes from the editing widget’s Attributes field in the Advanced tab.
-
The following snippet describes the interaction between the rich-text element and the editing widget.
import com.psddev.cms.db.RichTextElement;
import com.psddev.dari.util.CompactMap;
import com.psddev.dari.util.StringUtils;
public class AnotherLinkRichTextElement extends RichTextElement {
@Required
private Link link;
private String linkText;
public String getLinkText() {
return linkText;
}
public void setLinkText(String linkText) {
this.linkText = linkText;
}
@Override
public void fromBody(String body) {
setLinkText(StringUtils.unescapeHtml(body));
}
@Override
public String toBody() {
return getLinkText();
}
@Override
public void fromAttributes(Map<String, String> attributes) {
List<Attribute> createdAttributes = attributes.keySet()
.stream()
.map(key -> {
Attribute attribute = new Attribute();
attribute.setName(key);
attribute.setValue(attributes.get(key));
return attribute;
})
.collect(Collectors.toList());
link.setAttributes(createdAttributes);
}
@Override
public Map<String, String> toAttributes() {
Map<String, String> htmlAttributes = new CompactMap<>();
link.getAttributes()
.forEach(attribute -> htmlAttributes.put(attribute.getName(), attribute.getValue()));
return htmlAttributes;
}
}
-
Declares a
Link
field that contains the attributes in an HTML<a>
element. -
Declares a field, getter, and setter for the link text (the text inside an HTML
<a>
element. -
Populates the field Link Text in the editing widget, unescaping any escaped HTML entities that may have been received from the rich-text element.
-
Retrieves the value in the field Link Text, and uses it as the link text when constructing an HTML
<a>
element. -
Reads the attribute map passed from the rich-text element and populates the Attributes list in the editing widget’s Advanced tab.
-
Reads the Attributes list in the editing widget’s Advanced tab, and uses it to construct the attributes in an HTML
<a>
element.
Brightspot stores rich-text elements in XML format, similar to the following:
{
"caption": "Here is a link <a href=\"http://www.brightspot.com/\" target=\"_blank\" cursor=\"wait\" type=\"text/html\" >Brightspot</a>."
}
The element and attribute names you can use in a custom rich-text element are arbitrary, so you can design rich-text elements to fit your publishing needs. You then implement runtime parsers in view models that extract the elements and attributes from the database and populate the view.
The following steps outline how to design rich-text elements and attach them to the rich-text editor’s toolbar. Although the steps are specific to pull quotes, you can apply them to any custom rich-text element.
Step 1: Extend a rich-text element
All custom rich-text elements extend from RichTextElement .
import com.psddev.cms.db.RichTextElement;
import com.psddev.dari.db.Recordable;
import com.psddev.dari.util.StringUtils;
@Recordable.DisplayName("Pull Quote") 1
@RichTextElement.Tag( 2
value = "quote",
preview = true,
block = false,
root = true,
menu = "Enhancement")
public class PullQuoteRichTextElement extends RichTextElement {
@Required
private String quote;
public String getQuote() {
return quote;
}
public void setQuote(String quote) {
this.quote = quote;
}
@Override 3
public Map<String, String> toAttributes() {
return null;
}
@Override
public void fromAttributes(Map<String, String> attributes) {
}
@Override
public void fromBody(String body) {
setQuote(StringUtils.unescapeHtml(body));
}
@Override
public String toBody() {
return getQuote();
}
}
-
Specifies the rich-text element displays as a pull quote in the rich-text toolbar.
-
Specifies the presentation aspects of the rich-text element:
- The theme’s data files use the
value
element for creating the view. In this snippet, the data files must provision the rich-text element using the identifierquote
. - In the toolbar, the rich-text element appears under the menu item Enhancement.
@RichTextElement.Tag
annotation see @RichTextElement.Tag. - The theme’s data files use the
-
Overrides the methods
toAttributes
,fromAttributes
,fromBody
, andtoBody
. These methods provide the interface between the rich-text element and the associated editing widget. For details see Editing lifecycle of rich-text elements.
Step 2: Attach rich-text element to toolbar
import com.psddev.cms.rte.RichTextToolbar;
import com.psddev.cms.rte.RichTextToolbarItem;
import com.psddev.cms.rte.RichTextToolbarStyle;
public class CustomRichTextToolbar implements RichTextToolbar {
@Override
public List<RichTextToolbarItem> getItems() { 1
return Arrays.asList(
RichTextToolbarStyle.BOLD,
RichTextToolbarStyle.ITALIC,
RichTextToolbarStyle.UNDERLINE
RichTextToolbarStyle.ELEMENTS);
}
}
-
Attaches all custom rich-text elements to the toolbar.
Step 3: Create theme files
Under your project’s
styleguide
/ directory, create files for each field appearing in the rich-text element. For example, if a field
body
is typed as a rich-text field, then the theme’s files must provide the template, data file, and styling for the field
body
. As a best practice, ensure each file’s path and base name correspond to the rich-text element’s class. The following example provides an illustration for theme files corresponding to the class
PullQuoteRichTextElement
developed in Step 1.
./
└── <root>
├── src |
└── main |
└── java |
└── brightspot |
└── content |
└── article |
└── PullQuoteRichTextElement.java
└── styleguide
└── content
└── article
├── PullQuoteRichTextElement.hbs
├── PullQuoteRichTextElement.json
└── PullQuoteRichTextElement.less
For information about creating theming files, see Theme guide .
See also:
- Rendering rich text
- Rich-text toolbar
Subclasses of RichTextElement can implement the callbacks required for editing rich-text elements.
Inside the rich-text editor, clicking Edit fires two callbacks:
-
RichTextElement#fromBody
to populate the editing widget’s Link Text field and the Main tab of the Link field. -
RichTextElement#fromAttributes
to populate the editing widget’s Attributes field in the Advanced tab.
-
Inside the editing widget, clicking Save & Close fires two callbacks to create a traditional HTML link of the form
<a href="value” otherattribute="othervalue">link text</a>
:-
RichTextElement#toBody
to retrieve the link text from the editing widget’s Link Text field. -
RichTextElement#toAttributes
to retrieve the link’s attributes from the editing widget’s Attributes field in the Advanced tab.
-
The following snippet describes the interaction between the rich-text element and the editing widget.
import com.psddev.cms.db.RichTextElement;
import com.psddev.dari.util.CompactMap;
import com.psddev.dari.util.StringUtils;
public class AnotherLinkRichTextElement extends RichTextElement {
@Required
private Link link;
private String linkText;
public String getLinkText() {
return linkText;
}
public void setLinkText(String linkText) {
this.linkText = linkText;
}
@Override
public void fromBody(String body) {
setLinkText(StringUtils.unescapeHtml(body));
}
@Override
public String toBody() {
return getLinkText();
}
@Override
public void fromAttributes(Map<String, String> attributes) {
List<Attribute> createdAttributes = attributes.keySet()
.stream()
.map(key -> {
Attribute attribute = new Attribute();
attribute.setName(key);
attribute.setValue(attributes.get(key));
return attribute;
})
.collect(Collectors.toList());
link.setAttributes(createdAttributes);
}
@Override
public Map<String, String> toAttributes() {
Map<String, String> htmlAttributes = new CompactMap<>();
link.getAttributes()
.forEach(attribute -> htmlAttributes.put(attribute.getName(), attribute.getValue()));
return htmlAttributes;
}
}
-
Declares a
Link
field that contains the attributes in an HTML<a>
element. -
Declares a field, getter, and setter for the link text (the text inside an HTML <a> element.
-
Populates the field Link Text in the editing widget, unescaping any escaped HTML entities that may have been received from the rich-text element.
-
Retrieves the value in the field Link Text, and uses it as the link text when constructing an HTML <a> element.
-
Reads the attribute map passed from the rich-text element and populates the Attributes list in the editing widget’s Advanced tab.
-
Reads the Attributes list in the editing widget’s Advanced tab, and uses it to construct the attributes in an HTML <a> element.
Brightspot stores rich-text elements in XML format, similar to the following:
{
"caption": "Here is a link <a href=\"http://www.brightspot.com/\" target=\"_blank\" cursor=\"wait\" type=\"text/html\" >Brightspot</a>."
}
The element and attribute names you can use in a custom rich-text element are arbitrary, so you can design rich-text elements to fit your publishing needs. You then implement runtime parsers in view models that extract the elements and attributes from the database and populate the view.