Custom fields in PageBuilder Engine
Custom fields are implemented using React’s PropTypes library. They are available on both Feature and Chain type components.
PageBuilder Engine looks for a static property on your component named propTypes
, which should be an object. This object should contain a customFields
key, whose value is PropTypes.shape()
.PropTypes.shape()
expects a single argument, which is an object whose keys are the names of the custom fields you are enumerating, and the values being their PropTypes
.
Changing IDs and Types
When you add a feature or chain to a page or template, a configuration for it is saved in PageBuilder. If either the ID or the Type of a customField changes, it has an immediate impact on the previously added instances and their render.
The configuration saved on pages and templates no longer matches the configuration a feature or chain has, which results in the malformed or lost data of all customFields that have received a change.
To prevent any interference of old and new data, you must remove the feature or chain and re-add and reconfigure them on all pages and templates .
Types
bool
Also aliased as PropTypes.boolean
.
Description
Will produce a checkbox input in PageBuilder and return true
or false
depending on the selection.
Example
import PropTypes from 'prop-types';import React from 'react'
const MyComponent = (props) => { const { showDesc } = props.customFields
return ( <h1>Hello World!</h1> {showDesc && (<p>Lorem ipsum</p>)} )}
MyComponent.propTypes = { customFields: PropTypes.shape({ myBool: PropTypes.boolean })}
export default MyComponent
contentConfig()
Description
Specifies the content schema that this component is compatible with so that a PageBuilder user can select from a dynamic list of content sources that match that schema. Once the editor has selected the content source to use, PageBuilder allows the user to set the parameters of that content source so they can be used by the feature to fetch content.
The contentConfig
custom field returns an object with two keys to the feature: a string representing the content source name is returned to the component as contentService
, and the parameters to query the content source are returned as an object named contentConfigValues
.
Parameters
contentConfig(schemaName)
schemaName
(String, Array[String]): Represents the name of a schema of the required data. Schemas are no longer supported, but you can define the content sources and data structure that this component is compatible with. The String, Array[String] has to match theschemaName
on content sources. See Content Source API.
Example
import PropTypes from 'prop-types'import Consumer from 'fusion:consumer'import React, { Component } from 'react'
@Consumerclass Songs extends Component { constructor(props) { super(props)
const { songListConfig } = this.props.customFields
const { contentService, contentConfigValues } = songListConfig
this.fetchContent({ songList: { source: contentService, query: contentConfigValues, filter: '{ results { name } }' } }) }
render() { <ul> {this.state.songList.map(song => <li>{song.name}</li> )} </ul> }}
Songs.propTypes = { customFields: PropTypes.shape({ songListConfig: PropTypes.contentConfig('songSchema').tag({ group: 'Configure Content' }) })}
export default Songs
date
Description
Will produce a datepicker input in PageBuilder and return a string containing the user-selected date.
For PageBuilder Engine’s purposes, this is an alias for PropTypes.string
. It exists only to denote that this field should render a datepicker in PageBuilder.
Example
See PropTypes.string
example.
dateTime
Description
Will produce a date-and-time picker input in PageBuilder and return a string containing the user-selected date and time.
For PageBuilder Engine’s purposes, this is an alias for PropTypes.string
. It exists only to denote that this field should render a date-and-time picker in PageBuilder.
Example
See PropTypes.string
example.
disabled
Description
Will produce a disabled textarea in PageBuilder and return a string containing the value of the textarea. This is commonly used for custom fields that use plugins to set the field value rather than users editing the textarea directly.
For PageBuilder Engine’s purposes, this is an alias for PropTypes.string
. It exists only to denote that this field should render a disabled textarea in PageBuilder.
Example
See PropTypes.string
example.
Description
Will produce an email input in PageBuilder and return a string containing the email the user entered.
For PageBuilder Engine’s purposes, this is an alias for PropTypes.string
. It exists only to denote that this field should render an email input that validates proper email format in PageBuilder.
Example
See PropTypes.string
example.
json
Description
Will produce a textarea in PageBuilder and return a string containing the value of the textarea, which is expected to be a valid JSON string.
PageBuilder Engine will attempt to validate that the returned string is in proper JSON format, and will log a warning if this is not the case.
Example
import PropTypes from 'prop-types';import React from 'react'
const MyComponent = (props) => { const { jsonStr } = props.customFields
return ( <pre>{jsonStr}</pre> )}
MyComponent.propTypes = { customFields: PropTypes.shape({ jsonStr: PropTypes.json })}
export default MyComponent
kvp
Description
Will produce a series of “key/value pair” text inputs that allow PageBuilder Editor to set the keys and values of an object, and have that object returned to the component.
Example
import PropTypes from 'prop-types';import React from 'react'
const ElectionResults = (props) => { const { candidateVotePercent } = props.customFields
return ( <ul> {Object.keys(candidateVotePercent).map(candidateName => <li> <strong>{candidateName}</strong> has {candidateVotePercent[candidateName]} of the vote so far </li> )} </ul> )}
MyComponent.propTypes = { customFields: PropTypes.shape({ candidateVotePercent: PropTypes.kvp })}
export default MyComponent
label
Description
Will produce a simple label in PageBuilder displaying the name of the custom field and a description (if provided). This type of field is used for providing contextual information in the PageBuilder interface from a particular component. It does not return data back to PageBuilder Engine itself, it is purely for the PageBuilder editorial experience.
Example
See PropTypes.string
example.
list
Description
Will produce a series of text inputs in PageBuilder that allows the editor to enter many values, which will be returned as an array of strings to the component.
Example
import PropTypes from 'prop-types';import React from 'react'
const TopicsList = (props) => { const { topics } = props.customFields
return ( <ul> {topics.map(topic => <li>{topic}</li> )} </ul> )}
TopicsList.propTypes = { customFields: PropTypes.shape({ topics: PropTypes.list })}
export default TopicsList
number
Description
Will produce a number
input field in PageBuilder that allows users to enter a number value, which then gets returned to the component.
Example
import PropTypes from 'prop-types';import React from 'react'
const MyComponent = (props) => { const { description } = props.globalContent const { maxChars } = props.customFields
const slicedContent = description.slice(0, maxChars)
return ( <p>{slicedContent}</p> )}
MyComponent.propTypes = { customFields: PropTypes.shape({ maxChars: PropTypes.number })}
export default MyComponent
oneOf()
Also aliased as select()
Description
Will produce a select
input in PageBuilder that allows users to select from one of the enumerated options in the array. Values in the array can be matched to human-readable text via the labels
property passed to the Tag method.
To enable alpha sorting, pass ordered
property in the following ways:
- when ordered is set to false, the items will be placed in order as they are in a feature’s source code.
- when ordered is set to true, the items will be placed in alphabetical order.
- default: same as ordered is true.
Example
import PropTypes from 'prop-types';import React from 'react'
const MyComponent = (props) => { const { listType } = props.customFields const El = (listType === 'ol') ? 'ol' : 'ul' return ( <El> <li>Foo</li> <li>Bar</li> <li>Baz</li> </El> )}
MyComponent.propTypes = { customFields: PropTypes.shape({ listType: PropTypes.oneOf([ 'ol', 'ul' ]).tag({ labels: { ol: 'Ordered List', ul: 'Unordered List' }, ordered: false }) })}
export default MyComponent
richtext
Description
Will produce a textarea in PageBuilder and return a string containing the value of the textarea.
For PageBuilder Engine’s purposes, this is an alias for PropTypes.string
. It exists only to denote that this field should render a textarea in PageBuilder.
Example
See PropTypes.string
example.
string
Also aliased as text
Description
Will produce a text input in PageBuilder that allows users to type a string value, which then gets returned to the component.
Example
import PropTypes from 'prop-types';import React from 'react'
const MyComponent = (props) => { const { headline } props.customFields
return (<h1>{headline}</h1>)}
MyComponent.propTypes = { customFields: PropTypes.shape({ headline: PropTypes.string })}
export default MyComponent
url
Description
Will produce a URL input in PageBuilder and return a string containing the URL the user entered.
For PageBuilder Engine’s purposes, this is an alias for PropTypes.string
. It exists only to denote that this field should render a URL input that validates proper URL format in PageBuilder.
Example
See PropTypes.string
example.
Global Options
These options are available as properties/methods that can be added to any PageBuilder Engine PropType.
isRequired
Description
Denotes that a certain prop is required. Will throw warnings in development if the chosen prop is not present.
Example
...
MyComponent.propTypes = { customFields: PropTypes.shape({ headline: PropTypes.string.isRequired })}
export default MyComponent
tag()
Description
The tag()
method provides a way of adding additional metadata that PageBuilder requires about a custom field. It takes an object containing this metadata in key/value pair form as an argument.
Parameters
tag(optionMap)
optionMap
(Object): A map of metadata options about this particular custom field.
optionMap.defaultValue
(?): The default value this custom field should take.optionMap.description
(String): A text description about the purpose of this custom field for users to better understand it.optionMap.group
(String): The name of a group of common custom fields. PageBuilder will aggregate custom fields with the samegroup
name into a common UI interface element.optionMap.formPlugin
(String): The name of a plugin used by this custom field. See the Plugin API for more info.optionMap.format
(String): An ISO 8601 compliant date format string, for datepicker custom fields.optionMap.hidden
(Boolean): Whether to show or hide the custom field.optionMap.label
(Object or String): An object mapping an i18n locale short code to a translated string. Optionally, a String can be provided to always use the same human-readable label regardless of locale.optionMap.labels
(Object): An object mapping a value listed in the array of aoneOf
custom field to a more human-readable stringoptionMap.max
(Number): Maximum number allowed for anumber
type custom field.optionMap.min
(Number): Minimum number allowed for anumber
type custom field.optionMap.step
(Number): Interval to increase or decrease by for every change to anumber
type custom field.
Example
...
MyComponent.propTypes = { customFields: PropTypes.shape({ myNumberField: PropTypes.number.tag({ label: { en: 'My Number', es: 'Mi NĂşmero' }, group: 'examples', hidden: false, max: 100, min: 0, step: 5 }), mySelectField: PropTypes.oneOf([ 'foo', 'bar', 'baz' ]).tag({ defaultValue: 'bar', description: 'This custom field is useless', group: 'examples', labels: { foo: 'Foo', bar: 'Bar', baz: 'Baz' } }) })}
export default MyComponent