Frontastic component schemas
A Frontastic component schema defines which data is collected for the Frontastic component from the Frontastic studio and the API hub. This data is then made available to the Frontastic component automatically through the data
prop of the React part of the Frontastic component.
The authoritative instance for Frontastic component schemas is the JSON schema found in paas/libraries/common/src/json/tasticSchema.json
. You can use this schema for validation and auto-completion in your IDE.
Structure
The basic structure of a schema is as follows:
{
"tasticType": "<customer>/<project>/tasticIdentifier",
"name": "Readable name in Frontastic studio",
"icon": "wrap_text",
"schema": [
{
// ...
}
]
}
The tasticType
is the most important piece here as it connects the schema to the React component using the tastics.js
in your project and they must be identical to the mapping defined there. The name
is also important because this is what the user sees in the Frontastic studio. The icon
can be used to define a speaking icon from Material icons.
Schema section
The schema
section is an array of configuration sections (realized as the Frontastic component editor panel in the Frontastic studio). For simple Frontastic components, a single schema object works fine.
{
// ...
"schema": [
{
"name": "First section in Frontastic studio",
"fields": [
{
"label": "Label in Frontastic studio",
"field": "identifierUsedToAccessFieldInDataProp",
"type": "string"
},
// ...
]
},
{
"name": "Second section in Frontastic studio",
"fields": [
{
"label": "Label for field in Frontastic studio",
"field": "fieldIdentifierMustBeUnique",
"type": "string"
},
// ...
]
}
]
}
You can move around fields between these sections as you like because the resulting data
property will be flat (without the sections). They're only for visualization purposes in the studio. That also means that every field identifier (see below) must be unique across the whole schema. The only exceptions are fields that are part of a group
(also see below).
Each schema
section has a name
(the section headline in the component editor panel) and a number of fields
.
Fields
Each object in fields
consists of a similar structure which can slightly differ depending on the type
of the field:
{
// ...
"schema": [
{
// ...
"fields": [
{
// Required field properties
"label": "Label in Frontastic studio",
"field": "identifierUsedToAccessFieldInDataProp",
"type": "string",
// Optional field properties
"translatable": false,
"required": true,
"default": "Hello!"
},
// ...
]
},
]
}
Each field has a label
which is displayed to the user as the prompt to insert some information. The property field
determines how you can access this field in your Frontastic component code later. So, for this example, you would use props.data.identifierUsedToAccessFieldInDataProp
. Remember that field identifiers must be unique across a schema.
The type
determines what kind of information should be input by the user in the Frontastic studio. string
is the most simple one. You'll find a reference for all supported types and their options below.
The remaining properties of a field are optional and help you to configure the behavior of the field in the studio:
translatable
: Determines if the field value should be available in different languages (see Internationalization article for more information. This is available fortext
,string
, andmarkdown
fields. The default of this setting istrue
(see below).required
(default:false
): If the setting is mandatory in the Frontastic studio. You'll still need to check if the value is set in your Frontastic component code because it might not be loaded yet (asynchronous) or the user in the studio ignored the warning about a mandatory setting (for example, to store a draft).default
(defaultnull
): Define a custom default value you want to receive when the config is left empty in the studio.
Simple field types
There are a number of simple field types that are supported by Frontastic to allow different configuration inputs. The more complex types stream
, group
, tastic
, and custom
are explained further below.
Boolean
Description: A simple switch that returns true
or false
.
Code example:
//...
"fields": [
{
"label": "Whole tile clickable",
"field": "isClickable",
"type": "boolean",
"default": false
},
]
//...
Example of how it looks in the Frontastic studio:
String/Text
Default: translatable = true
Description: string
renders a 1-line input, while text
is a multi-line input field.
Code example for text
:
//...
"fields": [
{
"label": "Teaser Text",
"field": "teaserText",
"type": "text",
"default": null
},
]
//...
Example of how it looks in the Frontastic studio:
Code example for string
:
//...
"fields": [
{
"label": "Label",
"field": "label",
"type": "string"
},
]
//...
Example of how it looks in the Frontastic studio:
Markdown
Default: translatable = true
Description: Allows the user to write simply formatted text using Markdown (see our using the markdown editor article for more information). You'll receive the raw Markdown string and can render it in your component using paas/catwalk/src/js/component/markdown.jsx
.
Code example:
//...
"fields": [
{
"label": "Content",
"field": "text",
"type": "markdown",
"default": "* Enter\n* some\n* Markdown",
"translatable": true
},
]
//...
Example of how it looks in the Frontastic studio:
Number/Integer/Decimal
Description: Lets the user input a numeric value.
Code example:
//...
"fields": [
{
"label": "Space in px (Overrides Size field)",
"field": "spaceInPx",
"type": "integer",
"default": ""
}
]
//...
Example of how it looks in the Frontastic studio:
Enum
Description: Presents a select box to pick a single value from it. The name
of an enum value is displayed in the Frontastic studio while you receive the value
part in your Frontastic component code.
Code example:
// ...
"fields": [
{
"label": "Size",
"field": "size",
"type": "enum",
"required": false,
"values": [
{
"value": "xxs",
"name": "Extra Extra Small (4px)"
},
{
"value": "xs",
"name": "Extra Small (8px)"
},
{
"value": "sm",
"name": "Small (12px)"
},
{
"value": "md",
"name": "Medium (16px)"
},
{
"value": "lg",
"name": "Large (20px)"
},
{
"value": "xl",
"name": "Extra Large (24px)"
}
],
"default": "xl"
},
//...
Example of how it looks in the Frontastic studio:
Media
Description: Lets the user select an image from the Frontastic media library and configure some additional settings such as an alt
text, crop ratio, and where the crop anchor should be in the image.
You can influence if the user can select a ratio or pre-define a fixed value using:
Code example:
// ...
{
"name": "Image",
"helpText": "Customize your image",
"fields": [
{
"label": "Image",
"field": "image",
"type": "media",
"required": true
}
]
},
//...
Example of how it looks in the Frontastic studio:
You can also add options for the crops if you want to, like:
//...
"options": {
"ratio": "16:9"
}
//...
See the Image usage article for more info.
Node
Description: Lets the user select a page folder from the page folder tree in the site builder and returns the corresponding page folder ID. You can use the paas/catwalk/src/js/app/nodeLink.jsx
component to render a link to the corresponding page folder.
Code example:
//...
{
"label": "Node",
"field": "node",
"required": false,
"type": "node",
"default": null
},
//...
Example of how it looks in the Frontastic studio:
Reference
Description: A reference can either be a page folder (like from the node
type) or an external link URL. If you want to give the user the choice, use this type. You can use the paas/catwalk/src/js/component/reference.jsx
component to render the value of this type directly. For more info on this, please see Working with links.
Code example:
//...
{
"label": "Link",
"field": "reference",
"required": false,
"type": "reference",
"default": null
},
//...
Example of how it looks in the Frontastic studio:
Tree
Description: The user can select a page folder in the site builder and you'll receive the entire sub-tree of page folders that starts there. This is especially handy if you want to render a navigation.
Code example:
//...
{
"label": "Navigation Tree",
"field": "tree",
"type": "tree"
},
//...
Example of how it looks in the Frontastic studio:
Instant
Default: translatable = false
Description: The user will see an input box and when they click, they'll see a calendar and a clock to select a date and time. NOTE: The time and date selected is based on the users local time.
Code example:
//...
{
"label": "Countdown to",
"field": "countdownTo",
"type": "instant",
"default": "Fri Jul 15 2022 16:14:00 GMT+02"
},
//...
Example of how it looks in the Frontastic studio:
JSON
Description: This field type is meant for copy and paste of complex information (for example, exports from other systems). You can ask users to paste some JSON and will receive it automatically parsed to an object.
Code example:
//...
{
"label": "Teaser Json",
"field": "teaserJson",
"type": "json",
"default": null
}
//...
Example of how it looks in the Frontastic studio:
Data source fields
The field type stream
is special in the sense that you won't receive the user entered configuration, but the result from a data source query. For example, if you select the streamType: product-list
, the Frontastic studio user will be able to filter products from the commerce backend by various criteria. In your Frontastic component, you'll simply receive the products that are returned by this query.
Every field of type stream
needs a streamType
parameter:
//...
{
"name": "Stream selection",
"fields": [
{
"label": "title",
"field": "title",
"type": "string",
"default": ""
},
{
"label": "Description",
"field": "description",
"type": "string",
"default": ""
},
{
"label": "Data source",
"field": "data source",
"type": "stream",
"streamType": "product-list",
"default": null
}
]
},
//...
Example of how it looks in the Frontastic studio:
Possible values for streamType
are:
product-list
: A list of productsproduct
: A single productcontent-list
: A list of content objectscontent
: A single content object
In addition, there are streams that don't allow the user in the Frontastic studio to provide configuration but which you can nevertheless use to retrieve data on specific dynamic pages:
account-addresses
: A list of the consumer's stored addressesaccount-orders
: A list of the consumer's orders in the commerce backendaccount-wishlists
: All wishlists the consumer has in the backend
Complex input using group
In some cases, just a single input isn't enough. Then you typically don't want to have multiple fields like image1
, image2
, image3
but use a field of type group
to let the user in the studio create a flexible number of group elements as values for the field. The elements of a group
can contain any number of fields again. The basic configuration of a group
looks like this:
{
// ...
"schema": [
{
// ...
"fields": [
{
"label": "Image in the slider",
"field": "selectedImage",
"type": "group",
"min": 1,
"max": 5,
"fields": [
{
"label": "Image",
"field": "image",
"type": "media"
}
},
// ...
]
},
]
}
This schema creates a group
of media
fields. The user in the studio can add a number of media
items (at least 1, up to 5, min
/max
are optional) in the group
and as the value, you receive an array of these elements in your Frontastic component, for example:
this.props.data.sliderImages = [
{
"image": '// ...',
},
{
"image": '// ...',
},
// ...
]
To allow the user to provide a page folder and some text in addition to the image you can craft your schema like this:
{
// ...
"schema": [
{
// ...
"fields": [
{
"label": "Images in the slider",
"field": "sliderImages",
"type": "group",
"fields": [
{
"label": "Image",
"field": "image",
"type": "media"
},
{
"label": "Teaser text",
"field": "teaserText",
"type": "string"
},
{
"label": "Page folder link",
"field": "pageFolderLink",
"type": "node"
}
]
},
// ...
]
},
]
}
The corresponding structure in your Frontastic component code will be:
this.props.data.sliderImages = [
{
"image": '// ...',
"teaserText": '...',
"pageFolderLink": '123abc'
},
{
"image": '// ...',
"teaserText": '...',
"pageFolderLink": '424242'
},
// ...
]
Let's look at an example:
//...
{
"name": "Shipping countries",
"fields": [
{
"label": "Countries",
"field": "countries",
"type": "group",
"itemLabelField": "name",
"fields": [
{
"label": "Name",
"field": "name",
"translatable": false,
"required": true,
"type": "string"
},
{
"label": "Code",
"field": "code",
"translatable": false,
"required": true,
"type": "string"
}
],
"default": [
{
"name": "Germany",
"code": "DE"
},
{
"name": "United States of America",
"code": "US"
}
]
}
]
},
//...
And how that would look in the Frontastic studio:
Use a label as the first option along with
"itemLabelField": "name"
so that this is displayed in the component settings panel.
Help text
You can provide additional information to your users in the Frontastic studio by using the field types description
and image
. In contrast to normal fields, these don't expect the label
and field
properties, but only type
plus their specific value properties. As there's:
{
// ...
"schema": [
{
// ...
"fields": [
{
"type": "description",
"text": "I will be displayed in Frontastic studio as help."
},
{
"type": "image",
"url": "https://example.com/some/image.png"
},
// ...
]
},
]
}
Images can, for example, be hosted in your project or an external HTTPS secured file hosting.
Let's look at a description
example:
//...
"name": "Menu",
"fields": [
{
"type": "description",
"text": "Choose a few top categories to be displayed on top of the navigation. Selecting a top category will allow the consumer to navigate to its tree."
},
//...
And how it looks in the Frontastic studio:
You can also use helpText
which displays at the top of the section and appears on hover:
//...
{
"name": "Image",
"helpText": "Customize your image",
"fields: [
//...
}
//...
Example of how it looks in the Frontastic studio:
Updated over 1 year ago