This tutorial takes you through the process of creating a custom
trait.
A trait is an attribute or property of a visitor or visit, such as age
or gender, that you can use to personalize content.
We create a trait that detects the visitor’s operating system. Depending
on the detected user agent, we serve the visitor a page with a
personalized
component. We create two component variants named WINDOWS and
OS-X for a component with a text and an image.
The trait extracts the operating system from the
user agent in the HTTP header:
Windows users are served a component with text that refers to the
Windows system and a download link (ftp://mgnl.travel/maps-offline/windows.zip).
OS-X users are served a component with text that refers to the OS-X
system and a download link (ftp://mgnl.travel/maps-offline/osx.zip).
If neither system is detected, Magnolia serves the original version
of the component, containing generic text and a download link
(ftp://mgnl.travel/maps-offline/other-systems.zip).
Create a module
A trait is deployed with a Magnolia module. Create a module first.
Choose from these options depending on your skill level:
Option 1: Clone the project in Git
This option gives you a ready-made project that you can customize to
your needs.
Choose this option if you know how to work with a Magnolia project and
Git, and want to examine the code locally in your IDE.
Build the project into a JAR and deploy it to your Magnolia instance, or run the project in your IDE. To run it in an IDE, add the module as a
dependency to your Magnolia bundle POM file (see the next section).
Option 2: Add the project as a dependency to your bundle
Choose this option if you run Magnolia in your IDE, but don’t plan to
work on the code.
Add the project as a dependency in the POM files of your Magnolia
bundle.
In the dependencyManagement section of the DX Core bundle parent POM
file, add a dependency element with a version number:
In the dependencies section of the dx-core-webapp POM file, add a
dependency element without a version number:
If you use IBM WebSphere, add the dependency
element in the appropriate POM file of your webapp of choice.
If you are using a custom bundle, add the dependency element with a
version number in the POM file of your customized bundle.
Option 3: Download the module JAR
Choose this option if you are new to Magnolia and don’t have a
development environment (IDE). You can use the trait but won’t be able
to look at the code.
Copy the JAR into <CATALINA_HOME>/webapps/<contextPath>/WEB-INF/lib
folder. Typically this is
<CATALINA_HOME>/webapps/magnoliaAuthor/WEB-INF/lib.
Restart your Magnolia instance and
run
the Web update. This will install the documentation-trait-tutorial
module.
Registering a trait
Any module can register a trait. Magnolia observes the traits folder
in your module configuration and adds new traits to a trait registry.
Registered traits are then displayed to editors in the user interface.
Properties
Property
Description
<trait name>
required
Trait name. Choose a name that is easy for editors to understand such as
country, date or userAgent.
previewTraitFactory
optional
Name of the factory that instantiates a new trait. For preview purposes only.
The implementations for the cookieTrait, headerTrait and requestParameterTrait types are set.
ruleField
required
Field used to define permitted values for the trait. See Rule field below.
valueField
required
Field used to enter a single value to test personalized content
delivery. See Value field below.
converterClass
required
Converter class which must implement
info.magnolia.personalization.preview.parameter.PreviewParameterConverter<Object>.
traitClass
required
Trait class. Doesn’t have to explicitly implement an interface. Usually,
it is just a plain Java object which allows you to specify the trait and
its characteristics.
voterClass
required
Voter class which must extend AbstractBoolVoter<TraitCollector>. See
Voters.
defaultPreviewTrait
optional, default is false
Adds the trait to the Preview app. Set this property to true for
traits that editors preview content with routinely. It makes the Preview
app faster to use. If a trait is used rarely, leave the property out.
If the trait is expected to remain the same for all requests in the
current session, you can set the value to
info.magnolia.personalization.trait.storage.StorageAwareTraitCollector$SessionScopedTraitStorage,
which will avoid resolving the trait in each request. The trait will be
resolved once for the current session. The value is implemented for
example for the country trait in the default installation of Magnolia.
Rule field
A rule field defines values for the trait when you choose an audience.
For example, you need two rule fields to define a date range: one for
the start date and another for the end date. Magnolia uses the input
entered into the rule field(s) to construct a
voter. The voter then decides whether the
visitor or visit matches the rule or not. When the rule is met,
personalized content is delivered.
The rule field is displayed to users in the Choose audience dialog.
Choose a
field
definition class that lets the user specify the permitted values. In
some cases, a simple
text
field is enough (country). In others, for example, where you need the
user to select a value (new visitor, registered visitor, logged-in
visitor), a
select
field is appropriate. For more complex fields, use a
composite
field. See
List
of fields for more.
Field
definition class. The field must be known to the system. If you
introduce a new field and only want it available in your module,
configure it in the /modules/<module name>/fieldTypes node. See
Custom
fields.
transformerClass
required
Transformer class which must implement
info.magnolia.personalization.ui.SimpleTraitValueTransformer.
type
required/optional
Field type. In this case, it is a bean property of the superclass
(TextFieldDefinition) of the definition class. The type is not needed
in every case.
Value field
A value field is for previewing variants. The field is displayed to
users in the Preview app when viewing the page as a visitor.
When you enter a value that matches the rule, for example, Macintosh
in the image above, the voter tests the value against the rule and
Magnolia displays the content variant associated with the value.
JCR-specific configurations (classes or $types containing the word Jcr) are not supported in the Preview app except for jcrMultiValueField.
name
required
Must be the same as the <trait name>.
Registering a trait detector filter
Once you have registered the trait, provide a
TraitDetectorFilter and register it in the filter chain to make sure
the appropriate variant is served.
UserAgentDetectorFilter registration in the
filter
chain.
Property
Description
filters
required
Filters node
<filter name>
required
Filter name. Name the filter after your trait. Ideally, name the node to
match the trait registration node. In our
example the filter name is userAgent. The system doesn’t require that
both nodes have the same name, but it makes it easier to identify the
purpose of the filter.
class
required
Class that implements AbstractTraitDetectorFilter<Object>.
Position of the filter in the chain
Make sure the filter is in the right position in the chain. Filters are
executed in the order they are registered in the chain, from top to
bottom. You want to position the filter right after the contentType
filter.
When installing a module, you can define the position with
ModuleVersionHandler#getExtraInstallTasks.
publicclassPersonalizationExamplesModuleVersionHandlerextendsDefaultModuleVersionHandler{
@Overrideprotected List<Task> getExtraInstallTasks(InstallContext installContext){
List<Task> tasks = new ArrayList<Task>();
tasks.add(new FilterOrderingTask("userAgent", new String[]{"contentType"}));
return tasks;
}
}Copy
Creating component variants
Now you can create component variants and choose an audience using the
new trait.
The documentation-trait-tutorial module installs an example page named
maps-download that contains two custom variants of the Text and image
component.
It is not possible to specify an audience for the original.
The original acts as fallback (default) content when no variants match
the visitor.
Testing the result
You can test the personalized variants using a browser plugin or on
different computers running Windows and OS-X. User agent switcher
add-ons that allow you to spoof and mimic various user agents are
available for Chrome/Chromium, Firefox and many other browsers.
You should now be able to see different renderings of the page
containing the personalized variants of the Text and image component
depending on the user agent.