How to create a new version of Confluence page via Java API / Scriptrunner?
Asked by Kurt Rosivatz:

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.png](https://community.atlassian.com/t5/image/serverpage/image-id/91773iFBC15B48E02EA95A/image-dimensions/550x155?v=v2 "Screenshot_1 Testpage for Update - scriptrunnter.png")![Screenshot_2 Page History - Testpage for Update - scriptrunnter.png](https://community.atlassian.com/t5/image/serverpage/image-id/91772iFA44138AE63E9640/image-dimensions/530x150?v=v2 "Screenshot_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.png](https://community.atlassian.com/t5/image/serverpage/image-id/91771iB5E9AF63C47A6CBF/image-dimensions/498x149?v=v2 "Screenshot_3 Testpage for Update - scriptrunnter.png")![Screenshot_4 Page History - Testpage for Update - scriptrunnter.png](https://community.atlassian.com/t5/image/serverpage/image-id/91774i99E35DD3AD254618/image-dimensions/537x140?v=v2 "Screenshot_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


Answers:
author: Diego
body: Hello [@Kurt Rosivatz](/t5/user/viewprofilepage/user-id/3697968) !

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:
> * ++***[\[Atlassian Developer Community\] Confluence Development](https://community.developer.atlassian.com/c/Confluence)***++

Or if need be, reach out to Adaptavist:
> * ++***[@Ravi Sagar _Sparxsys_](/t5/user/viewprofilepage/user-id/853596)***++
> * ++***[@Nic Brough -Adaptavist-](/t5/user/viewprofilepage/user-id/781454)***++

Let us hear from you!

comments: author: Kurt Rosivatz
body: 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


author: Kurt Rosivatz
body: I finally found a solution myself by looking at the documentation of the [Versioned](https://docs.atlassian.com/ConfluenceServer/javadoc/7.3.5/com/atlassian/confluence/core/Versioned.html) 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.


author: Frank
body: 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>


author: aghilas
body: Hello [@Kurt Rosivatz](/t5/user/viewprofilepage/user-id/3697968) ,

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.png](https://community.atlassian.com/t5/image/serverpage/image-id/173095i3AC2DCE3A151089E/image-size/large?v=v2&px=999 "Screenshot_22.png")![Screenshot_23.png](https://community.atlassian.com/t5/image/serverpage/image-id/173112iD44995165A37CA72/image-size/large?v=v2&px=999 "Screenshot_23.png")![Screenshot_24.png](https://community.atlassian.com/t5/image/serverpage/image-id/173113iF37CDFA867322F65/image-size/large?v=v2&px=999 "Screenshot_24.png")


author: Putri Nur Dayana Kamarudin
body: Hi [@aghilas](/t5/user/viewprofilepage/user-id/4667195)

To update a page and create a new version, you will need to use [PageManager.SaveNewVersion](https://docs.atlassian.com/atlassian-confluence/6.2.0/index.html?com/atlassian/confluence/pages/PageManager.html) like the example below :

```
import com.atlassian.confluence.pages.PageManagerimport com.atlassian.sal.api.component.ComponentLocatordef 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!


author: aghilas
body: Hi [@Putri Nur Dayana Kamarudin](/t5/user/viewprofilepage/user-id/4226853)

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")
    }
}
```


Tags: addon-com.onresolve.confluence.groovy.groovyrunner

api

confluence-server

groovy

html

java

scriptrunner

server