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. 

This script also removes the hippotaxonomy:classifiable mixin, but some projects may have added that mixin on myproject.cnd level, so then that part should be removed from the script.
If hippotaxonomy:keys was chosen as path for the new field, there is no need to move property data. It's still a good idea to remove the hippotaxonomy:classifiable mixin.
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.

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?