Annotate Channel or Component Configuration Parameters with UI Directives
Introduction
Goal
Annotate channel or component configuration parameters with UI directives for the Experience manager or Channel Editor.
Background
End users can configure channels and page components through configuration dialogs in the Experience manager and Channel Editor, respectively. These configuration dialogs are rendered based on the parameters defined in a ChannelInfo or ParametersInfo interface. These interfaces and their methods can be annotated with specific UI directives to enable the Experience manager or Channel Editor to render the configuration dialog as intended.
Overview
Component | ParametersInfo | ChannelInfo | |||
interface | method | interface | method | ||
@ParametersInfo |
✓ |
||||
@FieldGroupList | ✓ | ✓ | |||
@FieldGroup | ✓ | ✓ | |||
@Parameter | ✓ |
✓ |
|||
@DropDownList | ✓ |
✓ |
|||
@JcrPath | ✓ |
✓ |
Component Class Annotations
The following annotations can be used on a delivery tier component class.
@ParametersInfo
Specifies the interface that defines the parameters of the annotated component. For example:
MyComponent.java
@ParametersInfo(type = MyComponentParamsInfo.class) public class MyComponent extends BaseHstComponent { ... }
Parameters Interface Annotations
The following annotations can be used on a ParametersInfo interface that defines the parameters of a component as well as on a ChannelInfo interface that defines the configuration parameters of a channel.
@FieldGroupList
Specifies a list of @FieldGroup annotations that together contain all configuration parameters. The order of the field groups determines the order in which they are rendered in the configuration dialog.
@FieldGroup
Specifies a list of configuration parameters to render in the configuration dialog. Each parameter is referenced by its name. The order of the names determines the order in which the parameters are rendered in the configuration dialog. For example:
MyComponentParamsInfo.java
@FieldGroupList({ @FieldGroup(titleKey = "address", value = { "street", "city" }), @FieldGroup(titleKey = "layout", value = { "size" }) }) public interface MyComponentParamsInfo { @Parameter(name = "street") String getStreet(); @Parameter(name = "city") String getCity(); @Parameter(name = "size", defaultValue="medium") @DropDownList({"small", "medium", "large"}) String getSize(); }
The title of a field group can be localized using a resource bundle.
Parameters Interface Method Annotations
Component Parameters and Channel Parameters
The following annotations can be used for getter methods of a ParametersInfo interface that defines the parameters of a component or a ChannelInfo interface that defines the configuration parameters of a channel.
@Parameter
Specifies the name of the parameter, an optional default value, and whether it's required or not. Options:
- name
The name of the parameter that will be stored in the hst:parameternames property. Must be unique per component.
- required
Whether this parameter is required or not. The Channel Editor only saves a component's parameters when all required parameters have been filled in. Default: false.
- displayName
The string displayed to the user as the label for the parameter field in the component's properties panel in the Channel Editor. Default: the same value as name. Alternatively, resource bundles can be used to localize the label.
If no other annotations are used, the widget in the CMS UI to edit the parameter depends on the return type of the annotated method:
Method Return Type |
CMS UI Widget |
java.lang.String |
Text field that accepts an alpha-numeric value for the parameter |
short, int, long, java.lang.Short, java.lang.Integer, java.lang.Long |
Text field that accepts only numeric values |
boolean, java.lang.Boolean |
Checkbox that sets 'true' or 'false' in the parameter value |
java.util.Date |
Date picker widget |
@DropDownList
There are multiple ways of setting up the dropdown values:
- Used for a getter that returns a String value from a predefined set of values:
@Parameter(name = "cssDisplay", displayName = "CSS Display") @DropDownList(value = {"inline", "block", "flex"}) String getCssDisplay();
The display name of each value can be localized using a resource bundle.
- The set of values can also be dynamically pulled from an implementation of org.hippoecm.hst.core.parameters.ValueListProvider:
@Parameter(name = "cssDisplay2", displayName = "CSS Display 2") @DropDownList(valueListProvider = CssDisplayValueListProvider.class) String getCssDisplay2();
- Starting from brXM 14.3, it's also possible to register a list of org.hippoecm.hst.core.parameters.ValueListProvider using the ValueListProviderService. In order to do that, it's required to inject the custom value list providers in a map called customValueListProviders in the platform Spring context in the cms webapp (the file path must match the pattern META-INF/hst-assembly/overrides/addon/org/hippoecm/hst/platform/*.xml):
<bean id="customValueListProviders" class="org.springframework.beans.factory.config.MapFactoryBean"> <property name="targetMapClass"> <value>java.util.HashMap</value> </property> <property name="sourceMap"> <map> <entry key="css-display-3" value="org.example.CssDisplayValueListProvider" /> </map> </property> </bean>
Then the ValueListProvider can be referenced from the parameter annotation using the key from the map above:
@Parameter(name = "cssDisplay3", displayName = "CSS Display 3") @DropDownList(valueListProviderKey = "css-display-3") String getCssDisplay3();
For examples, see BannerInfo.java, DemoChannelInfo.java, CssDisplayValueListProvider.java, and testprovider.xml in the Test Suite.
@JcrPath
Used for a getter that returns a path to a document as String value. The path can be set by picking a document. The path can be either absolute or relative, depending on the isRelative option. The CMS UI will display the name or the last path element of the document, and a button that opens a document picker. Options:
- isRelative
Whether the stored path is relative to the canonical content root path of the channel in which this annotation is used. The default is 'false', i.e. the stored path is absolute.
- pickerConfiguration
The root path of the CMS configuration to use for the picker, relative to /hippo:configuration/hippo:frontend/cms. Default value: "cms-pickers/documents".
To pick only images, use the value "cms-pickers/images".
To pick only documents, use the value "cms-pickers/documents-only". - pickerRootPath
The absolute root path to use in the picker, or an empty string if the channel content path is used. If configured it must start with a "/". Default value: "" (empty string).
- pickerInitialPath
The initial path to use in the picker if nothing has been selected yet, relative to the pickerRootPath. Use the path to a folder to initially open the picker in that folder. Use the path to the handle of a document to preselect that document. Use an empty string to use the default initial path of the picker. Default value: "" (empty string).
- pickerRemembersLastVisited
Whether the picker remembers the last visited path. Default: true.
- pickerSelectableNodeTypes
Types of nodes to be able to select in the picker. Default: empty list, resulting in the default behavior of the picker.
Localization
Field group titles, parameter names, parameter values (for parameters annotated with @DropDownList), and hint texts can be localized using a resource bundle (either repository-based or Java-based).
The resource bundle must have the same package and name as the parameters interface.
In the case of a repository-based resource bundle, the bundle is loaded from either /hippo:configuration/hippo:translations/hippo:hst/componentparameters or /hippo:configuration/hippo:translations/hippo:hst/channelparameters and corresponding YAML definitions should be added to the repository-data-application module, which get packaged with the CMS web application.
In the case of a Java-based resource bundle, the bundle should also be packaged with the CMS web application.
Example repository resource bundle YAML for component parameters defined in org.example.components.MyComponentParamsInfo:
definitions: config: /hippo:configuration/hippo:translations/hippo:hst/componentparameters/org: jcr:primaryType: hipposys:resourcebundles /example: jcr:primaryType: hipposys:resourcebundles /components: jcr:primaryType: hipposys:resourcebundles /MyComponentParamsInfo: jcr:primaryType: hipposys:resourcebundles /en: jcr:primaryType: hipposys:resourcebundle address: Address Information street: Street city: City layout: Layout Settings size: Size size#small: Small size#medium: Medium size#large: Large
Example Java-based resource bundle (.properties file):
address=Address Information street=Street city=City layout=Layout Settings size=Size size/small=Small size/medium=Medium size/large=Large
Hint Texts
To help users understand the purpose of a component or channel configuration parameter, include a property <parameter>.hint in the resource bundle. When such a property is present, a small 'information' icon will be rendered next to the parameter in the configuration dialog. Hovering over the icon will show the hint text.
Example of repository-based resource bundle YAML:
size.hint: Select a size
Example Java-based resource bundle properties:
size.hint=Select a size
Inheritance
Field groups of super interfaces are merged with the field groups of the sub interface. Parameters of field groups with the same title key are merged into one group.
A field group can include parameter names from super interfaces, and thereby re-order and re-group these parameters at will. Each parameter is only included once, so including a parameter from a super interface in the field group of a sub-interface will 'override' its position. Inherited field groups and parameters are scanned breadth-first.
If a super interface has resource bundles, they will also work for the sub interface. The resource bundles for the sub interface can override the super interface bundles by redefining the i18n key. Note that multiple inheritance and super interfaces of super interfaces also correctly inherit i18n resource bundles. For the bundle inheritance scanning of super interface, a breadth first super interface bundle scanning is done.
Troubleshooting
The features described on this page require certain dependencies and application configuration to be in place.
Make sure the hippo-plugin-selections-hst-client dependency is present in your implementation project. If not, add it to cms-dependencies/pom.xml:
<dependency> <groupId>org.onehippo.cms7</groupId> <artifactId>hippo-plugin-selections-hst-client</artifactId> </dependency>
Also make sure the Selection content beans are added to the hst-beans-annotated-classes context parameter in site webapp's web.xml:
XML
<context-param> <param-name>hst-beans-annotated-classes</param-name> <param-value>classpath*:org/onehippo/forge/selection/hst/contentbean/*.class</param-value> </context-param>