Hello,
I hope somebody can help us on the following:
We sometimes add new properties to existing document types or refactor them, but currently we have to go through all the documents manually and ‘migrate’ these documents afterwards.
What we want to achieve is to automatically migrate these documents and set or copy a specific value automatically.
For instance something like this:
For each documents in brX
if document.type = 'ProductGrid' then
if current.ProductGrid.ItemsPerRow is null or empty then
set ItemsPerRow = 5
end
if current.ProductGrid.ItemsPerGrid is null or empty then
set ItemsPerGrid = 30
end
end
end
Is there an easy solution for that?
Thanks for your help,
Thomas
Hello, you probably want to create a Groovy script and run it manually or during startup Updater Scripts - Bloomreach Experience Manager (PaaS/Self-Hosted) - The Fast and Flexible Headless CMS
Use xpath to target specific document types, or target all documents and then have the script determine the changes according to the type.
1 Like
Hi David,
thanks for the input and the link. I am not familiar with groovy, but I hope with the example in the documentation and some help from ChatGPT I created a working script. I am going to test it soon on our test environment.
The goal of the script is to go over all text documents, check if the new headlines compound exists and if not create the headlines compound containing the values of the old properties. We will see if it works that way.
XPath query:
/jcr:root/content/documents//element(*, myspace:Text)
package org.hippoecm.frontend.plugins.cms.dev.updater
import org.onehippo.repository.update.BaseNodeUpdateVisitor
import javax.jcr.Node
class TextUpdater extends BaseNodeUpdateVisitor {
private static final PROPERTY_HEADLINES_COMPOUND = 'myspace:headlines'
boolean doUpdate(Node node) {
if (!node.hasProperty(PROPERTY_HEADLINES_COMPOUND)) {
log.debug "Adding headlines compound to node ${node.path}"
// get current values from old fields
def headlineValue = node.getProperty('myspace:headline')
def headlineStyleValue = node.getProperty('myspace:headlineStyle')
def textStyleValue = node.getProperty('myspace:textStyle')
def alignmentValue = node.getProperty('myspace:alignment')
// create new headlines compound with values of old fields
def headlinesValue = "myspace:headline: $headlineValue, myspace:headlineStyle: $headlineStyleValue, myspace:textStyle: $textStyleValue, myspace:alignment: $alignmentValue"
// add new headlines compound
node.setProperty(PROPERTY_HEADLINES_COMPOUND, headlinesValue);
return true;
}
return false;
}
boolean undoUpdate(Node node) {
if (node.hasProperty(PROPERTY_HEADLINES_COMPOUND)) {
node.getProperty(PROPERTY_HEADLINES_COMPOUND).remove();
return true;
}
return false;
}
}
1 Like
your script looks good, but I think you should also remove the old properties node.getProperty(“old-property-name”).remove()
Hi quang_tran,
We tested the script on our test system yesterday afternoon and to be honest, it didn’t work at first. But we got it working, but we’ll test it some more and then I’ll be happy to post the working script here for others who have a similar problem.
We have not yet removed the old properties because they are currently still in use by the frontend and we can only remove them in a second step. But thanks for the input.
As promised here is our working script. The script checks for all our text documents if a headlines compound exists. If not it creates the headline compound in the document and sets the values from the old obsolete fields as values for the related field in the compound.
For all text documents where the headline compound already exists it overwrites the values of the headline compound fields with the values of the old fields.
After we have run this script we can then remove the old fields from our document structure and only the new headline compound is still there.
Hope this helps somebody with a similar use case.
package org.hippoecm.frontend.plugins.cms.dev.updater
import org.onehippo.repository.update.BaseNodeUpdateVisitor
import javax.jcr.Node
class TextUpdater extends BaseNodeUpdateVisitor {
private static final PROPERTY_HEADLINES_COMPOUND = 'myshop:headlines'
private static final PROPERTY_HEADLINES_TYPE = 'myshop:Headlines'
boolean doUpdate(Node node) {
if (!node.hasNode(PROPERTY_HEADLINES_COMPOUND)) {
log.debug "Adding headlines compound to node ${node.path}"
// get current values from old fields
def headlineValue = node.getProperty('myshop:headline').getString()
def headlineStyleValue = "h2"
if (node.hasProperty('myshop:headlineStyle')) {
headlineStyleValue = node.getProperty('myshop:headlineStyle').getString().toLowerCase()
if (headlineStyleValue.isBlank()) {
headlineStyleValue = "h2"
}
}
def textStyleValue = "normalCase"
if(node.hasProperty('myshop:textStyle')) {
textStyleValue = node.getProperty('myshop:textStyle').getString()
if (textStyleValue.isBlank()) {
textStyleValue = "normalCase"
}
}
def alignmentValue = "center"
if(node.hasProperty('myshop:alignment')) {
alignmentValue = node.getProperty('myshop:alignment').getString()
if (alignmentValue.isBlank()) {
alignmentValue = "center"
}
}
// create new headlines compound with values of old fields
def childNode = node.addNode(PROPERTY_HEADLINES_COMPOUND, PROPERTY_HEADLINES_TYPE)
childNode.setProperty("myshop:headline", headlineValue)
childNode.setProperty("myshop:headlineStyle", headlineStyleValue)
childNode.setProperty("myshop:textStyle", textStyleValue)
childNode.setProperty("myshop:alignment", alignmentValue)
return true;
} else if (node.hasNode(PROPERTY_HEADLINES_COMPOUND)) {
log.debug "Updating headlines compound of node ${node.path}"
// first read new Values
def headlinesNode = node.getNode(PROPERTY_HEADLINES_COMPOUND)
def newHeadlineValue = headlinesNode.getProperty('myshop:headline').getString()
def newHeadlineStyleValue = ""
if (headlinesNode.hasProperty('myshop:headlineStyle')) {
newHeadlineStyleValue = headlinesNode.getProperty('myshop:headlineStyle').getString().toLowerCase()
}
def newTextStyleValue = ""
if(headlinesNode.hasProperty('myshop:textStyle')) {
newTextStyleValue = headlinesNode.getProperty('myshop:textStyle').getString()
}
def newAlignmentValue = ""
if(headlinesNode.hasProperty('myshop:alignment')) {
newAlignmentValue = headlinesNode.getProperty('myshop:alignment').getString()
}
// read old values
def oldHeadlineValue = node.getProperty('myshop:headline').getString()
def oldHeadlineStyleValue = ""
if (node.hasProperty('myshop:headlineStyle')) {
oldHeadlineStyleValue = node.getProperty('myshop:headlineStyle').getString().toLowerCase()
}
def oldTextStyleValue = ""
if(node.hasProperty('myshop:textStyle')) {
oldTextStyleValue = node.getProperty('myshop:textStyle').getString()
}
def oldAlignmentValue = ""
if(node.hasProperty('myshop:alignment')) {
oldAlignmentValue = node.getProperty('myshop:alignment').getString()
}
// conditionally update the values in the new node
if(!oldHeadlineValue.isBlank()) {
headlinesNode.setProperty("myshop:headline", oldHeadlineValue)
}
if(!oldHeadlineStyleValue.isBlank()) {
headlinesNode.setProperty("myshop:headlineStyle", oldHeadlineStyleValue)
} else if(oldHeadlineStyleValue.isBlank() && newHeadlineStyleValue.isBlank()) {
headlinesNode.setProperty("myshop:headlineStyle", "h2")
}
if(!oldTextStyleValue.isBlank()) {
headlinesNode.setProperty("myshop:textStyle", oldTextStyleValue)
} else if(oldTextStyleValue.isBlank() && newTextStyleValue.isBlank()) {
headlinesNode.setProperty("myshop:textStyle", "normalCase")
}
if(!oldAlignmentValue.isBlank()) {
headlinesNode.setProperty("myshop:alignment", oldAlignmentValue)
} else if(oldAlignmentValue.isBlank() && newAlignmentValue.isBlank()) {
headlinesNode.setProperty("myshop:alignment", "center")
}
return true;
}
return false;
}
boolean undoUpdate(Node node) {
if (node.hasNode(PROPERTY_HEADLINES_COMPOUND)) {
node.getNode(PROPERTY_HEADLINES_COMPOUND).remove();
return true;
}
return false;
}
}