Abstract
We have to create a new Categorization app based on content app (See contact-app).
This app has to have the same functionality as the 4.5.x one (Categorization module)
Tasks
Create a new content-app module
Create a new categorization-app
- Configure App, sub app, workbench/sections/actions....
- Change the dependency
The categorization-app will stay in the same git repository as the current categorization module.
JCR
Node type
Create a new categorization node type
<nodeTypes
xmlns:rep="internal"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
xmlns:mix="http://www.jcp.org/jcr/mix/1.0"
xmlns:mgnl="http://www.magnolia.info/jcr/mgnl"
xmlns:jcr="http://www.jcp.org/jcr/1.0">
<!-- custom node types -->
<nodeType name="mgnl:category" isMixin="false" hasOrderableChildNodes="true" primaryItemName="">
<supertypes>
<supertype>mgnl:content</supertype>
</supertypes>
</nodeType>
</nodeTypes>
Workspace
Create and configure a new categorization workspace.
Workspace name : categorization
Migration
Create a simple migration task for Data migration.
Field
Create a new multi-selection field.
Target :
Additional requirement:
This field should have the ability by configuration to store the related information in the following format:
multiValueProperty. One multi-property valueIdentifier
<sv:property sv:name="categories" sv:type="String" sv:multiple="true"> <sv:value>ab9437db-ab2c-4df5-bb41-87e55409e8e1</sv:value> <sv:value>d7ba9d64-b7b8-4b93-8a3d-ecd14a049bb8</sv:value> <sv:value>e75cc729-fdf8-4154-9b5f-4a52ea2beab7</sv:value> </sv:property>Path
<sv:property sv:name="categories" sv:type="String" sv:multiple="true"> <sv:value>/categorization/Sports</sv:value> <sv:value>/categorization/Art</sv:value> <sv:value>/categorization/News</sv:value> </sv:property>
subNodes (multiple). Child node created for each entry, complete with associated properties.<sv:node sv:name="relatedUUID"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>dataItemNode</sv:value> </sv:property> <sv:property sv:name="jcr:mixinTypes" sv:type="Name" sv:multiple="true"> <sv:value>mix:lockable</sv:value> </sv:property> <sv:property sv:name="jcr:uuid" sv:type="String"> <sv:value>4d26a546-556e-4a3d-8f2a-eab3a67ddc60</sv:value> </sv:property> <sv:property sv:name="jcr:createdBy" sv:type="String"> <sv:value>admin</sv:value> </sv:property> <sv:node sv:name="756d0705-d629-479f-9"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>dataItemNode</sv:value> </sv:property> <sv:property sv:name="jcr:mixinTypes" sv:type="Name" sv:multiple="true"> <sv:value>mix:lockable</sv:value> </sv:property> <sv:property sv:name="jcr:uuid" sv:type="String"> <sv:value>b3f89a69-3c6e-4c8e-b79c-deab5cfa0168</sv:value> </sv:property> <sv:property sv:name="jcr:createdBy" sv:type="String"> <sv:value>admin</sv:value> </sv:property> <sv:property sv:name="relatedUUID" sv:type="String"> <sv:value>756d0705-d629-479f-910d-b3a27855550b</sv:value> </sv:property> </sv:node> <sv:node sv:name="1124b03d-09d9-41f3-b"> <sv:property sv:name="jcr:primaryType" sv:type="Name"> <sv:value>dataItemNode</sv:value> </sv:property> <sv:property sv:name="jcr:mixinTypes" sv:type="Name" sv:multiple="true"> <sv:value>mix:lockable</sv:value> </sv:property> <sv:property sv:name="jcr:uuid" sv:type="String"> <sv:value>90d96a80-028a-4b31-9319-b7e1b1ebd203</sv:value> </sv:property> <sv:property sv:name="jcr:createdBy" sv:type="String"> <sv:value>admin</sv:value> </sv:property> <sv:property sv:name="relatedUUID" sv:type="String"> <sv:value>1124b03d-09d9-41f3-b7c6-b07222a378b6</sv:value> </sv:property> </sv:node> </sv:node>list. Comma delimited list. (With Identifier and Path)<sv:property sv:name="categories" sv:type="String" sv:multiple="false"> <sv:value>ab9437db-ab2c-4df5-bb41-87e55409e8e1,d7ba9d64-b7b8-4b93-8a3d-ecd14a049bb8,e75cc729-fdf8-4154-9b5f-4a52ea2beab7</sv:value> </sv:property>json. JSON (JavaScript Object Notation) style. Useful when one entry contains multiple values (one-to-many relationship)
Not yet implemented.
Implementation
Mockup & Flow
- Multi-select field appear empty (if no selection where already made) or with the currently stored values.
- By clicking the Select button, the configured sub-app appear, allows to perform a selection.
By clicking save on the sub-app, this will populate the related input field. - By configuration, the single Select element can be set as read only
- or as editable.
Configuration
The MultiLinkFieldDefinition allows the user to select multiple values in a single field. Depending on the configuration, it can be used to store multiple text entries or multiple internal links. In the latter case, the user can browse for the link target using the repository explorer. The only relevant generic property is defaultValue.
Add Field Image
Class: info.magnolia.ui.form.field.definition. inherit all configuration from MultiLinkFieldDefinitioninfo.magnolia.ui.form.field.definition.LinkFieldDefinition
| Property | Description | Default value |
|---|---|---|
saveModeType | Specifies the structure the data will be saved in. | |
multiPropertyDelegateClass |
| SingleValueHandler |
allowChangesOnSelected | Define if a user can perform a changes on a already or newly created Link. If the selected link is displayed as read only. | |
buttonSelectAddLabel | Optional. Button label displayed on the Add button. Typically retrieved from a message bundle. |
Populate Node Name based on Property
This is needed in order to set the Category JCR Node name based on the Category name.
Possibilities:
- Concept - File Upload#FileUpload-GenericFieldlistenermechanismandconfiguration
- Create a Specific Save Action with a definition referring an implementation class that generate the JCR Node Name based on.
- ActionDefinition
- getName()
- getLabel()
- ...
- ActionRestrictionsDefinition getRestrictions()
- getNodeNameProperty()
- default should be 'name'
- nodeName/propertyName
Decision:
Add a default behavior to info.magnolia.ui.form.action.SaveFormAction :
- If the related
Itemhas a property calledjcrName
Set Node Name with the value of the propertyjcrName. - If the related
Itemhas no property calledjcrNameAND a property calledname
Set Node Name with the value of the propertyname. - In all other cases, use the default property name ('default')
If like for the contact-app, you need to define another logic to generate the Node name, create a new Action that extends info.magnolia.ui.form.action.SaveFormAction and override SaveFormAction.setNodeName(Node node, JcrNodeAdapter item)
STK / Demo Project
Adapt the bootstrap files and dependency.
- Categorization depend on STK, but Demo-Project bootstrap files into Categorization.

