Creating custom traits with complex fields
This page provides code and configuration examples of creating custom traits with multi and complex fields.
The rule field is implicitly wrapped inside MultiField in Magnolia 6.2.x. Please keep this in mind when configuring fields and use the examples below as a reference.
|
Creating a trait with a multi field
Definition
#traitClass has to be unique, creating multiple traits with multiField requires using different List implementation per trait
traitClass: java.util.List
converterClass: info.magnolia.personalization.preview.parameter.ListParameterConverter
voterClass: info.magnolia.personalization.preview.ui.app.field.ListVoter
defaultPreviewTrait: true
valueField:
$type: jcrMultiValueField
name: multiFieldTrait
canRemoveItems: false
field:
$type: textField
ruleField:
$type: compositeField
properties:
list:
$type: jcrMultiValueField
field:
$type: textField
Voter
package traits;
import info.magnolia.personalization.trait.TraitCollector;
import info.magnolia.voting.voters.AbstractBoolVoter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class ListVoter extends AbstractBoolVoter<TraitCollector> {
private List<String> list = new ArrayList<>();
@Override
protected boolean boolVote(final TraitCollector traitCollector) {
return Optional.ofNullable(traitCollector)
.map(collector -> collector.getTrait(List.class))
.map(list::containsAll)
.orElse(false);
}
public void setList(List<String> list) {
this.list = list;
}
}
Trait detector filter
This example filter detects all cookie names.
package traits;
import info.magnolia.personalization.trait.AbstractTraitDetectorFilter;
import info.magnolia.personalization.trait.TraitCollector;
import info.magnolia.personalization.trait.TraitDetectionException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.inject.Provider;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ListDetectorFilter extends AbstractTraitDetectorFilter<List<String>> {
public ListDetectorFilter(Provider<TraitCollector> traitCollectorProvider) {
super(traitCollectorProvider);
}
@Override
protected List<String> detect(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws TraitDetectionException {
return Arrays.stream(httpServletRequest.getCookies())
.map(Cookie::getName)
.collect(Collectors.toList());
}
@Override
protected Class getTraitClass() {
return List.class;
}
}
Creating a trait with a complex field
Definition
#traitClass has to be unique, creating multiple traits with multiField requires using different Map implementation per trait
traitClass: java.util.Map
converterClass: info.magnolia.personalization.preview.ui.app.field.MapPreviewConverter
voterClass: info.magnolia.personalization.preview.ui.app.field.MapTraitVoter
defaultPreviewTrait: true
valueField:
name: complexFieldTrait
$type: textField
placeholder: key=value
ruleField:
$type: compositeField
properties:
key:
$type: textField
value:
$type: textField
Voter
package traits;
import info.magnolia.personalization.trait.TraitCollector;
import info.magnolia.voting.voters.AbstractBoolVoter;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
public class MapTraitVoter extends AbstractBoolVoter<TraitCollector> {
private String key;
private String value;
@Override
protected boolean boolVote(TraitCollector traitCollector) {
return Optional.ofNullable(traitCollector)
.map(collector -> collector.getTrait(Map.class))
.map(map -> Objects.equals(map.get(key), value))
.orElse(false);
}
public void setKey(String key) {
this.key = key;
}
public void setValue(String value) {
this.value = value;
}
}
Trait detector filter
This example filter detects all cookies.
package traits;
import info.magnolia.personalization.trait.AbstractTraitDetectorFilter;
import info.magnolia.personalization.trait.TraitCollector;
import info.magnolia.personalization.trait.TraitDetectionException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.inject.Provider;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
public class MapDetectorFilter extends AbstractTraitDetectorFilter<Map<String, Cookie>> {
public MapDetectorFilter(Provider<TraitCollector> traitCollectorProvider) {
super(traitCollectorProvider);
}
@Override
protected Map<String, Cookie> detect(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws TraitDetectionException {
return Arrays.stream(httpServletRequest.getCookies())
.collect(Collectors.toMap(Cookie::getName, Function.identity()));
}
@Override
protected Class getTraitClass() {
return Map.class;
}
}