Migrate to the Taxonomy Field in 15.3
Introduction
As of brXM 15.3, a new taxonomy field type is available in the document type editor, as part of a larger set of taxonomy improvements.
This page describes how implementation projects can move from an existing, mixin-based taxonomy type to the new field type that behaves similar to regular field types.
Set up
This guide assumes a brXM 15.2 project with at least one document type that has a taxonomy field, set up manually or by Essentials, as described for the legacy taxonomy mixin at Taxonomy Plugin Configuration.
Upgrade and migrate
Upgrade to brXM 15.3.0
The normal upgrade steps for a minor release should be performed.
Building locally and running on an existing storage should present no problems. On hippotaxonomy.cnd level, some extra properties will be added, notably the hippotaxonomy:defaultLocale on taxonomy level, which can be checked using the Console app.
Optimize taxonomy tree data structure
There is an optional, though recommended, step to upgrade the taxonomy tree data structure to be more performant, see "Upgrade Considerations" in JCR Tree Model Restructuring in 15.3.
Add the new taxonomy field type
As admin, from the document type editor, add a new taxonomy field from the Primitive Field section to the document type.
In the field properties in the bottom right, configure the Path, Required, Default Caption and Hint appropriately. Configure the taxonomy.name property to the JCR node name of the taxonomy that this field should work with.
It’s possible to localize the caption and hint like the other fields, see Add Internationalization (i18n) To Document Types.
Easier delivery side migration
The new taxonomy field is designed to work with a JCR property that belongs to the project’s namespace, like any other field. However, it may be wanted to keep the delivery side unchanged, so then it is possible to choose hippotaxonomy:keys as path for the new field. Assumption is that the content can have any property, i.e. has the hippostd:relaxed mixin.
Remove the old taxonomy field type
As admin, from the document type editor, remove the existing taxonomy field from the document type.
Script for moving the key values on existing documents
Existing document instances have the category keys saved in a property hippotaxonomy:keys which is defined, on CND level, by the hippotaxonomy:classifiable mixin. A Groovy Updater script should be written and bootstrapped in a YAML file in the local project, in order to move the data from one property to another.
Example script
See below a pretty straightforward example script to move the property values.
package org.hippoecm.frontend.plugins.cms.admin.updater import org.hippoecm.repository.util.JcrUtils import org.onehippo.repository.update.BaseNodeUpdateVisitor import javax.jcr.Node import javax.jcr.NodeIterator import javax.jcr.RepositoryException import javax.jcr.Session import javax.jcr.query.Query import org.onehippo.taxonomy.api.TaxonomyNodeTypes /** * Groovy script to move category values from the standard hippotaxonomy:keys * property to a new project namespaced property. * * XPath query: //element(*, myproject:mydocument) * Parameters: { "keysProperty" : "hippotaxonomy:keys", * "newTaxonomyProperty" : "myproject:myproperty" } */ class MoveTaxonomyKeys extends BaseNodeUpdateVisitor { boolean doUpdate(Node node) { def classifiableMixin = TaxonomyNodeTypes.NODETYPE_HIPPOTAXONOMY_CLASSIFIABLE def keysProperty = parametersMap["keysProperty"] def newTaxonomyProperty = parametersMap["newTaxonomyProperty"] String[] keys = JcrUtils.getMultipleStringProperty(node, keysProperty, null) if (keys == null) { log.debug "Not copying values to ${newTaxonomyProperty}: no ${keysProperty} on node ${node.path}" return false } log.debug "Copying values from ${keysProperty} to ${newTaxonomyProperty} on node ${node.path}" node.setProperty(newTaxonomyProperty, keys) node.getProperty(keysProperty).remove() if (node.isNodeType(classifiableMixin)) { node.removeMixin(classifiableMixin) } return true } boolean undoUpdate(Node node) { throw new UnsupportedOperationException('Updater does not implement undoUpdate method') } boolean logSkippedNodePaths() { return false } boolean skipCheckoutNodes() { return false } Node firstNode(final Session session) throws RepositoryException { return null } Node nextNode() throws RepositoryException { return null } }
Delivery tier considerations
If dynamic content beans are inactive, a method similar to the getKeys() method (as described for the legacy taxonomy mixin in Taxonomy Plugin Delivery Tier) is to be added to the HST content bean.
If the project is using dynamic content beans (by default a project is), then the new property will be available for your front-end without further changes.
In the Delivery API, a taxonomy field will show the field like in the example below, with a taxonomyValues entry as an taxonomyAllValues entry, meaning with ancestors:
"taxonomy": { "taxonomyValues": [{ "key": "my-sub-category", "label": "My Sub Category", "keyPath": "1/my-category/my-sub-category/", "labelPath": "1/My Category/My Sub Category/" }], "taxonomyAllValues": [{ "key": "my-sub-category", "label": "My Sub Category", "keyPath": "1/my-category/my-sub-category/", "labelPath": "1/My Category/My Sub Category/" }, { "key": "my-category", "label": "My Category", "keyPath": "0/my-category/", "labelPath": "0/My Category/" } ], "taxonomyName": "myTaxonomy" }
Deployment
Since adding fields to and removing fields from document types is a developer’s effort, the updated document type is stored in YAML files in the project’s code base. A deployment step is needed for the changes to take effect on standing environments like test, staging, production.
The Groovy script for moving the key values on existing documents is to be bootstrapped via YAML into the registry at /hippo:configuration/hippo:update/hippo:registry and to be run in the environment.