How to create a new version of Confluence page via Java API / Scriptrunner?

Kurt Rosivatz
Contributor
April 23, 2020

I am trying to manipulate a Confluence page via Adaptavist ScriptRunner for Confluence and the Java API. Changing the content of the page works as expected but the change ist not correctly reflected in the page history - the content is overwritten with the new version the version count is increased but the old version is simply lost.

Here's my setup to reproduce this (Confluence Server 7.0.5, Scriptrunner 5.9.0)

  1. I create a page with title "Test for Update" with one paragraph text "Content"
  2. Looking at the page history it shows version v.1 created 9:07
  3. I run the script in Scriptrunner console (see code below)
  4. Opening the page shows the correctly manipulated content - all seems fine
  5. Looking now at the page history again it shows version v.2. (correct) with the same timestamp 9:07 altough the script ran 9:08 and version v.1 is simply lost - no way to track the changes or revert to v.1

That's my script code:

import com.atlassian.sal.api.component.ComponentLocator

import com.atlassian.confluence.pages.PageManager
import com.atlassian.confluence.pages.Page
import com.atlassian.confluence.core.DefaultSaveContext
import com.atlassian.confluence.core.Modification

import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import org.jsoup.nodes.Document

PageManager pageman = ComponentLocator.getComponent(PageManager)

def page = pageman.getPage("scriptrunner", "Testpage for Update")
def src=page.getBodyAsString()

def doc = Jsoup.parse(src)
doc.outputSettings().syntax(Document.OutputSettings.Syntax.xml);

def element = doc.getElementsContainingText("Content")

if (element.size()>0) {
element[0].text("Updated Content")
pageman.saveNewVersion(page, new Modification<Page>() {
public void modify(Page p) {
p.version = p.version + 1
p.bodyAsString = doc.body().toString()
}
}, DefaultSaveContext.MINOR_EDIT);
}
else {
log.warn("no content found")
}

 Some screenshots to document the behaviour:

1.) v.1 of page with page history:

Screenshot_1 Testpage for Update - scriptrunnter.pngScreenshot_2 Page History - Testpage for Update - scriptrunnter.png

2.) After running script - correctly modified - incorrect page history, v.1 lost, timestamp wrong:

Screenshot_3 Testpage for Update - scriptrunnter.pngScreenshot_4 Page History - Testpage for Update - scriptrunnter.png

I tried using

pageman.saveContentEntity(page, DefaultSaveContext.MINOR_EDIT)

instead of

pageman.saveNewVersion(page, new Modification<Page>() {
public void modify(Page p) {
p.version++
p.bodyAsString = doc.body().toString()
}
}, DefaultSaveContext.MINOR_EDIT);

leading to the same result.

So what's the correct why to create a new version of the page?

Any help and suggestions highly appreciated.

Kurt

 

1 answer

1 accepted

0 votes
Answer accepted
Diego
Atlassian Team
Atlassian Team members are employees working across the company in a wide variety of roles.
April 29, 2020

Hello @Kurt Rosivatz !

It is always nice to see and advanced usage of the platform tools, however I believe you will have better results by asking for direction from more specialized people from our Developer Community.

You can check all things development here:

Or if need be, reach out to Adaptavist:

Let us hear from you!

Kurt Rosivatz
Contributor
May 4, 2020

Hi,

Thanks, I'll give it a try in the developer community https://community.developer.atlassian.com/t/how-to-create-a-new-version-of-confluence-page-via-java-api/37912 

Regards,

Kurt

Kurt Rosivatz
Contributor
May 22, 2020

I finally found a solution myself by looking at the documentation of the Versioned interface in Confluence API.

So that's the relevant piece of code:

def page = pageManager.getPage("scriptrunner", "Test")
def source = page.getBodyAsString()

Page oldVersion = page.clone() as Page

oldVersion.convertToHistoricalVersion()
oldVersion.setOriginalVersion(page)

def modifiedSource = /* modify the source */

page.setBodyAsString(modifiedSource)
pageManager.saveContentEntity(page, oldVersion, DefaultSaveContext.BULK_OPERATION)

Looking a this new article (with solves my the problem I wrote the script for):

https://community.atlassian.com/t5/Confluence-articles/Bulk-Updating-Page-Content-in-Confluence-Server-using/ba-p/1385821

It's seems that my solution can be simplyfied to

pageManager.saveNewVersion(page) { pageObject ->
  pageObject.setBodyAsString(modifiedSource)
}

There is still a problem whit the page history. It shows incorrect values for the modifiers of the page in the history in some situations.

Like Rostyk Chuma likes this
Frank August 24, 2021

The solution discussed here is relying on the now (since version 7.3) deprecated PageManager.getPage() method. A version of the code avoiding this and using the new ContentManager can be found in my post at https://community.atlassian.com/t5/Confluence-questions/How-to-change-page-contents-from-Version-7-3-without-getting/qaq-p/1785445

aghilas
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
December 9, 2021

Hello @Kurt Rosivatz ,

I wrote a little method that allows me to update a page, but, I have the same problem as you on the page history and I wonder if you  solve the problem?

Screenshot_22.pngScreenshot_23.pngScreenshot_24.png

Putri Nur Dayana Kamarudin December 16, 2021

Hi @aghilas 

To update a page and create a new version, you will need to use PageManager.SaveNewVersion like the example below :

import com.atlassian.confluence.pages.PageManager
import com.atlassian.sal.api.component.ComponentLocator

def pageManager = ComponentLocator.getComponent(PageManager)
def page = pageManager.getPage('MB', 'test update page') //You can change this line to point to the right space and page.
pageManager.saveNewVersion(page) { pageObject ->
            pageObject.setBodyAsString("test script")
        }

 Hope this helps!

aghilas
I'm New Here
I'm New Here
Those new to the Atlassian Community have posted less than three times. Give them a warm welcome!
December 16, 2021

Hi @Putri Nur Dayana Kamarudin

thanks for your reply, i ended up finding the source which caused the bug on my code.

it comes from the line pageToUpdate.setVersion(v+1), it just had to be deleted, too bad there is no exception thrown when running my code so that this kind of bug does not occur ^^

I share my method for who wants to use it
static def updateBodyPage(Space space,Page pageToUpdate, String body, boolean addParentLabel,boolean disableLabel){
ContentEntityObject previousVersionOfPage = (ContentEntityObject) pageToUpdate.clone();
if (body != '') {
def bodyContent = new BodyContent(pageToUpdate, body, BodyType.XHTML)
pageToUpdate.setBodyContent(bodyContent)
}

if(!disableLabel){
if(addParentLabel){
List<Label> labelsParents=pageToUpdate.getParent().getLabels()
for(Label lab:labelsParents){
labelManager.addLabel(pageToUpdate,lab)
}
}
}

pageManager.saveContentEntity(pageToUpdate, previousVersionOfPage, null)
//solution 2
/* pageManager.saveNewVersion(pageToUpdate,new Modification<Page>() {
public void modify(Page p) {
p.setBodyAsString(body)
}
})*/
if (!pageManager.getPage(space.getKey(), pageToUpdate.getTitle())) {
throw new IllegalStateException("Unable to update a page ${pageToUpdate.getTitle()}")
} else {
logger.info("The page ${pageToUpdate.getTitle()} is updated")
}
}

 

Suggest an answer

Log in or Sign up to answer
TAGS
AUG Leaders

Atlassian Community Events