Magnolia 5.3 reached end of life on June 30, 2017. This branch is no longer supported, see End-of-life policy.
The value of a form field is typically stored in a single property in the repository. A text field named firstName
stores its value in a property firstName
. Use a property transformer to read and write values in a different way.
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.
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 override the default. Add the transformerClass
property into your field definition and set its value to a fully-qualified class name.
Default transformer classes:
info.magnolia.ui.form.field.transformer.basic.BasicTransformer
info.magnolia.ui.form.field.transformer.composite.CompositeTransformer
For switchable fields: info.magnolia.ui.form.field.transformer.composite.SwitchableTransformer
For multivalue field: info.magnolia.ui.form.field.transformer.multi.MultiValueTransformer
Other available transformer classes:
info.magnolia.ui.form.field.transformer.composite.DelegatingCompositeFieldTransformer
info.magnolia.ui.form.field.transformer.multi.DelegatingMultiValueFieldTransformer
info.magnolia.ui.form.field.transformer.composite.NoOpCompositeTransformer
info.magnolia.ui.form.field.transformer.multi.MultiValueJSONTransformer
info.magnolia.ui.form.field.transformer.multi.MultiValueChildrenNodeTransformer
info.magnolia.ui.form.field.transformer.multi.MultiValueChildNodeTransformer
info.magnolia.ui.form.field.transformer.multi.MultiValueSubChildrenNodeTransformer
Best practice
The delegating transformers 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.
The
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 exist yet.
Transformer class: info.magnolia.ui.form.field.transformer.basic.BasicTransformer
Here is an example dialog with some text fields:
The BasicTransformer
stores the field values like this in the JCR repository:
Node name | Value |
---|---|
mmonroe |
|
firstName | Marilyn |
lastName | Monroe |
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 in the field definition.
Here is an example field definition where type
is set to Date
. Magnolia will store the field value as a date object.
Node name | Value |
---|---|
eventDate | |
class | info.magnolia.ui.form.field.definition.TextFieldDefinition |
type | Date |
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.
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.
Node name | Value |
---|---|
simpleText | Simple English text |
simpleText_de | Einfache deutsche Text |
simpleText_fr | Simple text en français |
Composite fields that consist of multiple child fields use the
CompositeTransformer
by default. The CompositeTransformer
stores each child field value as a single property.
Transformer class: info.magnolia.ui.form.field.transformer.composite.CompositeTransformer
Here is a composite event
field. It consists of a text field and a date field.
The CompositeTransformer
stores the values like this:
Node name | Value |
---|---|
eventdate | 2013-10-31T20:30:00.00+02:00 |
eventtitle | Halloween |
The 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 storage property name.
Transformer class: info.magnolia.ui.form.field.transformer.composite.DelegatingCompositeFieldTransformer
Here is a composite field event that contains a title field and a date field.
The field is defined using a DelegatingCompositeFieldTransformer
:
Node name | Value |
---|---|
event |
|
fields |
|
title | |
class | info.magnolia.ui.form.field.definition.TextFieldDefinition |
label | Title |
date | |
class | info.magnolia.ui.form.field.definition.DateFieldDefinition |
label | Date |
class | info.magnolia.ui.form.field.definition.CompositeFieldDefinition |
label | Event |
transformerClass | info.magnolia.ui.form.field.transformer.composite.DelegatingCompositeFieldTransformer |
A normal CompositeTransformer
would store values like this:
Node name | Value |
---|---|
eventdate | 2013-10-31T20:30:00.00+02:00 |
eventtitle | Halloween |
The DelegatingCompositeFieldTransformer
stores values like this:
Node name | Value |
---|---|
date | 2013-10-31T20:30:00.00+02:00 |
title | Halloween |
When i18n=true
this transformer delegates localization to the child fields. Add the
i18n=true
property in the parent field AND in any child fields. The property needs to be added to both levels.
Node name | Value |
---|---|
date | Oct 31, 2013 12:00:00 AM |
date_de | Nov 1, 2013 12:00:00 AM |
title | Halloween |
title_de | Allerheiligen |
Use the
NoOpCompositeTransformer
for a composite field that is inside a multivalue parent field. "NoOp" means no operation – the 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
.
Transformer class: info.magnolia.ui.form.field.transformer.composite.NoOpCompositeTransformer
Switchable fields use a SwitchableTransformer by default. This transformer stores the selected field value as a single suffixed property.
Transformer class: info.magnolia.ui.form.field.transformer.composite.SwitchableTransformer
Here is a switchable text editor field. It consists of alternative plainText
and richText
fields.
The 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 to the start of the child property name.
Node name | Value |
---|---|
editor | richText |
editorplainText | Boo! Halloween is around the corner. |
editorrichText | <p><strong>Boo!</strong></p> Halloween is around the corner. |
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 the DelegatingMultiValueTransformer when nesting more than two levels of fields. The other multivalue transformers can handle only two levels.
MultiValueTransformer
is the default transformer for multivalue fields. The transformer stores field values in a LinkedList<T>
collection. The LinkedList 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.
Transformer class: info.magnolia.ui.form.field.transformer.multi.MultiValueTransformer
Here is a multivalue field that consists of a text field.
The MultiValueTransformer
stores the values as a JCR multivalue property that looks like a typical array.
Node name | Value |
---|---|
shoppingList | [milk, cookies, pizza] |
MultiValueJSONTransformer stores the values as a comma-separated list of Strings.
Use this transformer only for simple fields such as text, date and checkbox.
Transformer class: info.magnolia.ui.form.field.transformer.multi.MultiValueJSONTransformer
Here is a multivalue field that consists of a text field.
The MultiValueJSONTransformer
stores the values like this:
Node name | Value |
---|---|
shoppingList | milk, cookies, pizza |
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.
Transformer class: info.magnolia.ui.form.field.transformer.multi.DelegatingMultiValueFieldTransformer
Here is a multivalue field that consists of a text field.
This is how the nested fields are defined when using DelegatingMultiValueTransformer
:
Node name | Value |
---|---|
shoppingList | |
field | |
class | info.magnolia.ui.form.field.definition.TextFieldDefinition |
name | shoppingItem |
class | info.magnolia.ui.form.field.definition.MultiValueFieldDefinition |
label | Shopping List |
transformerClass | info.magnolia.ui.form.field.transformer.multi.DelegatingMultiValueFieldTransformer |
The DelegatingMultiValueFieldTransformer
stores the values like this:
Node name | Value |
---|---|
shoppingList0 | |
shoppingItem | milk |
shoppingList1 | |
shoppingItem | cookies |
shoppingList2 | |
shoppingItem | pizza |
When i18n=true
this transformer creates nodes with a locale suffix. The translated values are stored in properties under the nodes. Add the
i18n=true
property in the parent field AND in any child fields. The property needs to be added to both levels.
Node name | Value |
---|---|
shoppingList0 | |
shoppingItem | milk |
shoppingList1 | |
shoppingItem | cookies |
shoppingList2 | |
shoppingItem | pizza |
shoppingList0_de | |
shoppingItem | Milch |
shoppingList1_de | |
shoppingItem | Kekse |
shoppingList2_de | |
shoppingItem | Pizza |
Use the more versatile DelegatingMultiValueTransformer instead of this transformer if you can.
The 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.
Transformer class: info.magnolia.ui.form.field.transformer.multi.MultiValueChildrenNodeTransformer
Here is a multivalue field that consists of a text field.
The MultiValueChildrenNodeTransformer
stores the values like this:
Node name | Value |
---|---|
00 |
|
shoppingList | milk |
01 |
|
shoppingList | cookies |
02 |
|
shoppingList | pizza |
Use the more versatile DelegatingMultiValueTransformer instead of this transformer if you can.
MultiValueSubChildrenNodeTransformer first creates a node for the parent multivalue field. It then stores the child fields as numbered properties.
Transformer class: info.magnolia.ui.form.field.transformer.multi.MultiValueChildNodeTransformer
Here is a multivalue field that consists of a text field.
The MultiValueSubChildNodeTransformer
stores values like this:
Node name | Value |
---|---|
shoppingList |
|
0 | milk |
1 | cookies |
2 | pizza |
Use the more versatile DelegatingMultiValueTransformer instead of this transformer if you can.
MultiValueSubChildrenNodeTransformer first creates a node for the parent multivalue field. It then stores the child fields as subnodes and their values as properties.
Transformer class: info.magnolia.ui.form.field.transformer.multi.MultiValueSubChildrenNodeTransformer
Here is a multivalue field that consists of a text field.
The MultiValueSubChildrenNodeTransformer
stores values like this:
Node name | Value |
---|---|
shoppingList |
|
milk |
|
shoppingList | milk |
cookies |
|
shoppingList | cookies |
pizza |
|
shoppingList | pizza |
Use the more versatile DelegatingMultiValueTransformer instead of this transformer if you can.
This transformer is equivalent to MultiValueChildrenNodeTransformer
but it is able to handle a composite field as the child of the multivalue parent.
Transformer class: info.magnolia.ui.form.field.transformer.multi.MultiValueSubChildrenNodePropertiesTransformer
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.
The MultiValueSubChildrenNodePropertiesTransformer
stores each composite field as an item (node) and the values of the child fields as properties.
Node name | Value |
---|---|
event | |
00 | |
date | Oct 31, 2013 12:00:00 AM |
title | Halloween |
01 | |
date | Dec 31, 2013 12:00:00 AM |
title | New Year's Eve |
02 | |
date | Jan 31, 2014 12:00:00 AM |
title | Chinese New Year |
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 the DelegatingMultiValueTransformer and the DelegatingCompositeFieldTransformer.
Here's how transforming values is delegated:
DelegatingMultiValueTransformer
on multivalue field flights
creates a new Item and passes it to composite field flight
.from
, to
and seats
in order to initialize their own properties and Items.from
and to
add their text properties to the Item.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:
Node name | Value |
---|---|
flights0 | |
seats0 | |
seat | 15A |
seats1 | |
seat | 15B |
from | Boston |
to | San Francisco |
flights1 | |
seats0 | |
seat | 21E |
seats1 | |
seat | 21F |
from | San Francisco |
to | Boston |