The value of a form field is typically stored in a single property. For
example, text field firstName stores its value in a property
firstName. This page explains how to read and write values in
different ways using property transformers.
Property transformer is a layer that translates the stored values into
something the user can edit and vice versa. This is useful for complex
fields such as
multivalue
and
composite
where more than one property is needed to store the entire field value.
The transformer stands between the form and the JCR
Item
representation, which means that individual form fields are not directly
accessed by the Item.
Transformer classes
Property transformer classes define how field values are stored in the
repository. Each field has a default transformer class. You don’t need
to define a class unless you want to change the default. To change the
class, add a transformerClass property to your
field
definition and set its value to a fully qualified transformer class
name.
Default transformer classes:
For simple fields such as
Text
and
Date:
info.magnolia.ui.form.field.transformer.basic.BasicTransformer
For
composite
fields:
info.magnolia.ui.form.field.transformer.composite.CompositeTransformer
For
switchable
fields:
info.magnolia.ui.form.field.transformer.composite.SwitchableTransformer
For
multivalue
fields:
info.magnolia.ui.form.field.transformer.multi.MultiValueTransformer
The delegating transformer classes should be your first choice since
they are the most versatile. If you can, use
DelegatingCompositeFieldTransformer or
DelegatingMultiValueFieldTransformer rather than the other available
classes.
BasicTransformer
BasicTransformer stores the field value in a single property. The property has the same
name as the field definition node. You can provide a different name with
a name property in the
field
definition. This transformer creates a new property if the property
does not yet exist.
The BasicTransformer stores the field values like this in the JCR
repository:
Setting a property type
All JCR properties have a type. The basic transformer uses the String
type for all properties by default. You can use a different type by
adding a type property to the
field
definition.
Example field definition with type is set to Date. Magnolia will
store the field value as a date object.
form:
tabs:
- name: tabText
label: Text
fields:
- name: title
fieldType: text
label: Event
type: DateCopy
If you define a defaultValue, that value will be converted to the
desired type too. If you don’t define a default value, the property will
have a null start value.
i18n support
If a field supports translation, an i18n language suffix is added to the
property name.
For example, a simpleText field that supports translation has suffixes
en, de and fr. In this example, English is the default (fallback)
language so the en suffix is not used.
Property node name
Value
simpleText
Simple English text
simpleText_de
Einfache deutsche Text
simpleText_fr
Simple text en français
Composite transformers
CompositeTransformer
CompositeTransformer stores each child field value as a single property.
Composite
fields, which consist of multiple child fields, use
CompositeTransformer by default.
This composite event field consists of a
text
field and a
date
field.
CompositeTransformer stores the values like this:
Property node name
Value
eventdate
2015-10-31T20:30:00.00+02:00
eventtitle
Halloween
DelegatingCompositeFieldTransformer
DelegatingCompositeFieldTransformer stores each child field value as a single property. The difference
between this transformer and the other composite transformers is that it
uses the child field name as the storage property name.
Example composite field definition containing a
text
field and
date
field that uses DelegatingCompositeFieldTransformer:
form:
tabs:
- name: tabEvent
label: Event
fields:
- name: composite
fieldType: composite
transformerClass: info.magnolia.ui.form.field.transformer.composite.DelegatingCompositeFieldTransformer
label: Event
fields:
- name: title
fieldType: text
label: Title
- name: date
fieldType: date
label: DateCopy
CompositeTransformer would store values like this:
Property node name
Value
eventdate
2015-10-31T20:30:00.00+02:00
eventtitle
Halloween
DelegatingCompositeFieldTransformer stores values like this:
Property node name
Value
date
2015-10-31T20:30:00.00+02:00
title
Halloween
When i18n=true this transformer delegates localization to the child
fields. WARNING: Add the i18n=true property in the parent field AND
in any child fields. The property needs to be added to both levels.
Property node name
Value
date
Oct 31, 2015 12:00:00 AM
date_de
Nov 1, 2015 12:00:00 AM
title
Halloween
title_de
Allerheiligen
NoOpCompositeTransformer
Use NoOpCompositeTransformer for a
composite
field that is inside a
multivalue
parent field. NoOp means no operation – NoOpCompositeTransformer
does not perform any writeToItem or readFromItem operations, it just
acts as a property container. The transformer of the parent multivalue
field does the reading and writing of the item structure to the
repository. You can use any of the
multivalue transformers below in the
parent. The parent transformer passes the properties to the
NoOpCompositeTransformer as a Vaadin
PropertysetItem.
Here is a switchable text editor field. It consists of alternative
text
and
rich
text fields.
SwitchableTransformer stores the values like this. The parent option
field has one property (editor) and each child field has its own
property (editorplainText, editorrichText). The name of the parent
field is appended before the child property name.
Property node name
Value
editor
richText
editorplainText
Boo! Halloween is around the corner.
editorrichText
<p><strong>Boo!</strong></p> Halloween is around the
corner.
Note that Magnolia discards the values for unselected options when
changes are saved. In the example above, only the value entered for
editorplainTextoreditorRichtext is stored.
Multivalue transformers
Use multivalue transformers with
multivalue
fields. They are capable of storing multiple values, even in cases where
the multivalue parent field contains a
composite
field.
Use
DelegatingMultiValueTransformer
when nesting more than two levels of fields. The other multivalue
transformers can handle only two levels.
MultiValueTransformer
MultiValueTransformer is the default transformer for
multivalue
fields. The transformer stores field values in a LinkedList<T>
collection. The linked list is then automatically converted to a JCR
multivalue property when persisted to the JCR. In the repository it
looks like a typical array: comma-separated and enclosed in square
brackets.
Use this transformer only when the multivalue parent contains
a single field such as text, date and checkbox.
Here is a
multivalue
field that consists of a
text
field.
MultiValueJSONTransformer stores the values like this:
Property node name
Value
shoppingList
milk, cookies, pizza
DelegatingMultiValueTransformer
DelegatingMultiValueFieldTransformer delegates the responsibility of storing field values to the parent
field. In doing so, this transformer creates a list of Item objects. The
child field uses the Item to create and retrieve its own properties.
Delegation makes it possible to nest unlimited levels of fields. For
example, create a composite field which contains a multivalue field
which contains a switchable field and so on.
Use DelegatingMultiValueTransformer when nesting more than
two levels of fields. The other multivalue transformers can only handle
two levels max.
Here is a
multivalue
field that consists of a
text
field.
This is how the nested fields are defined when using
DelegatingMultiValueTransformer:
form:
tabs:
- name: tabMain
label: Main
fields:
- name: shoppingList
fieldType: multiValue
label: Shopping list
transformerClass: info.magnolia.ui.form.field.transformer.multi.DelegatingMultiValueFieldTransformer
field:
fieldType: text
name: shoppingitemCopy
DelegatingMultiValueFieldTransformer stores the values like this:
When i18n=true this transformer creates nodes with a locale suffix.
The translated values are stored in properties under the nodes.
WARNING: Add the i18n=true property in the parent field AND in any
child fields. The property needs to be added to both levels.
MultiValueChildrenNodeTransformer doesn’t create a node for the
multivalue parent field at all. It creates nodes for the child fields
and stores their values as properties. This structure is equivalent to
the JCR structure of the form Item.
MultiValueSubChildrenNodeTransformer first creates a node for the parent multivalue field. It then stores the
child fields as subnodes and their values as properties.
MultiValueSubChildrenNodePropertiesTransformer is equivalent to
MultiValueChildrenNodeTransformer
but it is able to handle a composite field as the child of the
multivalue parent.
Define a no-op transformer for the composite child field.
Since the parent multivalue field handles the read and write operations,
set the composite field’s transformerClass to
info.magnolia.ui.form.field.transformer.composite.NoOpCompositeTransformer.
Here is a multivalue event field. Each event is a composite field that
consists of a title and a date.
MultiValueSubChildrenNodePropertiesTransformer stores each composite
field as an item (node) and the values of the child fields as
properties.
Which transformer should I use?
I have a multi-value field with a simple field inside (e.g. text,
single-select, date, link): all multi-value transformers may be used.
I have a multi-value field with a complex field inside
(e.g. composite, switchable, multi-selection, or any other field with a
custom transformerClass): only delegating transformers should be used
(same goes for nested composite & switchable fields).
Combining delegating transformers
In this complex example we nest four levels of fields. To book a seat on
a flight you enter a departure city, arrival city and select one or more
seats depending on the number of passengers.
We need to use delegating field transformers since normal non-delegating
transformers can only handle two nesting levels. Also, since we mix
multivalue and composite fields we need to use both
DelegatingMultiValueTransformer
and the
DelegatingCompositeFieldTransformer.
It is not possible to change the order of the fields by using the
delegating transformer classes. These classes only delegate to other
independent transformer classes which do not know about each other. The
new order of the fields would not be kept after saving the change.
Here’s how transforming values are delegated:
DelegatingMultiValueTransformer on multivalue field flights
creates a new Item and passes it to composite field flight.
The Item is passed to the composite child fields from, to and
seats, in order to initialize their own properties and Items.
Text fields from and to add their text properties to the Item.
Nested composite field seats uses the Item to create a subitem and
sends the subitem to its child field seat.
The values are stored in the JCR repository like this: