- Created by Robert Reiner, last modified on 14. Feb 2020
projectdoc Toolbox
The Web API Extension for the projectdoc Toolbox can be employed to make bulk changes to documents. Since there is no safety net, these actions need to be take with care. This tip introduces a way to conduct this task.
Bulk changes on Confluence pages are usually conducted via the Confluence REST API. Using cURL, a bookmarklet, userscript, or any other form of REST client will do the trick. The Web API Extension for the projectdoc Toolbox provides additional REST services to access projectdoc documents and spaces. There are also services to access a particular property value or services to create documents from descriptors.
In case you use the REST API make sure that you do not delete valuable information. Usually you need recent backup and test your scripts on a copy of your production environment. The following tip shows how to lower the risk of unintentional data loss. A backup will be still required, but the changes of needing it are reduced.
Get in action!In this Tip you will learn by an example, how to define a search to find the documents you want to bulk change, define this change, apply it to a test document and finally do the real change.
In our example we assume, that some documents of Doctype Category which all have a property Type with value Type1 already exist.
The goal is to change all these documents to have value Type2
for the property Type, instead of having the value Type1.
Prerequisites
There are a number of options to access the Web API. For this tip two tools may be a valid choice, depending on using the change one time or multiple times. In case it is a one-shot, you could use the REST API Browser. In case you need it multiple times or consider to share the call, you could use cURL as part of a shell script.
Both approaches require the Web API Extension (available on the Atlassian Marketplace, version 6.2.0) for the projectdoc Toolbox
Get in action! Choosing the first option, using the REST API Browser from Confluence, please make sure you are using the latest version 3.2.3 (or later; see our blog post Resolved: REST API Browser showing API documentation again! for details).
Point your browser to: https://myserver.example.com/confluence/plugins/servlet/restbrowser#/resource/projectdoc-1-document
Uncheck "Show only public APIs" and insert "projectdoc
" in the search box on the top left side to see all projectdoc REST-API calls we provide.
Get in action! Choosing the seconf option prefer to use cURL (version 7.18, or later) and jq (version jq-1.5-1 or later). cURL is used in command lines or scripts to transfer data. jq is a lightweight and flexible command-line JSON processor.
Using cURL in combination with netrc is a very easy and quite secure way to handle your credentials for Confluence. The following netrc configuration (~/.netrc
) for linux systems allows to run the authentication without providing credentials on the command line (for more information and other options we recomend the tip: REST Login to Confluence with cURL).
machine www.example.com
login jane.doe
password XmysecretpasswordX
Protect your credentials!
.netrc file should only be readable and writable for you (-rw------- 1 jane.doe example 1356 Jan 21 08:44 /home/jane.doe/.netrc
)
In the following steps this tip pretends that you have chosen the second option using cURL.
Cautious Approach using the REST API
Since using the Web API does not provide a way to undo unintended changes, we provide a way to double check the implication of your actions.
In this example we show how to
- determine the documents you want to apply changes
- prepare the change
- apply the changes to one test document
- apply the changes to all documents
Get in action! Let us start by defining a query searching for documents of Doctype Category containing a property named Type with value Type1
.
curl -s -n -G "https://www.example.com/confluence/rest/projectdoc/1/document.json?select=Name,Type&from=MYEXAMPLE&max-hit-count=100&expand=property&max-result=100" \ --data-urlencode "where=$<Doctype>=[category] AND $<Type>=[Type1]" | jq .
Short explanation:
- The options
-s -n -G
stand for silent, use .netrc and use HTTP GET method - Followed by the URL to your Confluence server and the REST service for documents
- The query path may contain all parameters that do not need to be URL-encoded directly to the URL, that is: the parameter values do not contain a reserved chars:
";
" | "/
" | "?
" | ":
" | "@
" | "&
" | "=
" | "+
" | "$
" | ",
" - Each parameter that contains a value needed to be encoded use the option "
--data-urlencode
" (may be more than one)
in the example above its just one: the where condition (read here more on Search Tips) - Last but not least pipe "
|
" the result tojq
to receive a formatted result
(the punctuation mark ".
" followed after a whitespace followingjq
: "jq .
" is mandatory!)
{ "size": 2, "start-index": 0, "max-result": 2, "id-list": "128816586,128816588", "document": [ { "id": 128816586, "property": [ { "name": "Name", "value": "<ac:structured-macro ac:name=\"projectdoc-transclusion-parent-property\" ac:schema-version=\"1\" ac:macro-id=\"e8c27607-adfd-42e4-ace2-c2474ac3771c\"><ac:parameter ac:name=\"add-link\">false</ac:parameter><ac:parameter ac:name=\"property-name\">Name</ac:parameter></ac:structured-macro> / <ac:structured-macro ac:name=\"projectdoc-transclusion-property-display\" ac:schema-version=\"1\" ac:macro-id=\"8f80206a-419f-47cd-a099-da64c676a21d\"><ac:parameter ac:name=\"property-name\">Short Name</ac:parameter></ac:structured-macro>", "controls": "<br />" }, { "name": "Type", "value": "<ac:structured-macro ac:name=\"projectdoc-name-list\"><ac:parameter ac:name=\"doctype\">category-type</ac:parameter><ac:parameter ac:name=\"render-no-hits-as-blank\">true</ac:parameter><ac:parameter ac:name=\"names\">Type1</ac:parameter><ac:parameter ac:name=\"property-restrict-value-range\">true</ac:parameter><ac:parameter ac:name=\"property\">Type</ac:parameter></ac:structured-macro>", "controls": "" } ], "section": [] }, { "id": 128816588, "property": [ { "name": "Name", "value": "<ac:structured-macro ac:name=\"projectdoc-transclusion-parent-property\" ac:schema-version=\"1\" ac:macro-id=\"ac8cd350-faef-4367-8750-3739d5535286\"><ac:parameter ac:name=\"add-link\">false</ac:parameter><ac:parameter ac:name=\"property-name\">Name</ac:parameter></ac:structured-macro> / <ac:structured-macro ac:name=\"projectdoc-transclusion-property-display\" ac:schema-version=\"1\" ac:macro-id=\"471c11ea-4ab7-4fc4-96f8-8c9b95a264ea\"><ac:parameter ac:name=\"property-name\">Short Name</ac:parameter></ac:structured-macro>", "controls": "<br />" }, { "name": "Type", "value": "<ac:structured-macro ac:name=\"projectdoc-name-list\"><ac:parameter ac:name=\"doctype\">category-type</ac:parameter><ac:parameter ac:name=\"render-no-hits-as-blank\">true</ac:parameter><ac:parameter ac:name=\"names\">Type1</ac:parameter><ac:parameter ac:name=\"property-restrict-value-range\">true</ac:parameter><ac:parameter ac:name=\"property\">Type</ac:parameter></ac:structured-macro>", "controls": "" } ], "section": [] } ] }
Explanation:
- The result is starting with some general information about the
size
and theid-list
, which we will need later - In this example the query has two documents with id 128816586 and id 128816588 as query result and for each document two properties Name and Type are returned
Check! Check! Check!
Double and triple check the result set!
Make sure it is correct, as the changes in step 4 will be applied to the documents in this result set!
From the step above fetch the value of the JSON result property id-list
for later usage.
In this example it is 128816586,128816588
.
Get in action! Now prepare the new value for the property Type
in a file "document.json
" (read more on changing documents → Documents Service / PATCH)
{ "property": [ { "name": "Type", "value": "<ac:structured-macro ac:name=\"projectdoc-name-list\"><ac:parameter ac:name=\"doctype\">category-type</ac:parameter><ac:parameter ac:name=\"render-no-hits-as-blank\">true</ac:parameter><ac:parameter ac:name=\"names\">Type2</ac:parameter><ac:parameter ac:name=\"property-restrict-value-range\">true</ac:parameter><ac:parameter ac:name=\"property\">Type</ac:parameter><ac:parameter ac:name=\"\" /></ac:structured-macro>", "controls": "", "position": "replace" } ] }
Explanation:
- Insert the whole Confluence macro as value for the property and change the property value from
Type1
toType2
(the new value) - Confluence macros have a
schema-version
anda macro-id
, it is recommended to remove them - Please remember to escape all quotes in the property value!
The Web API Extension provides other options to change the value of a property. Please read below the Information on More Options to Change the Values.
We recommend to apply the changes now to one single test document. Preferable this step could be executed in a test environment.
So create a text document, fetch its page id e.g. by viewing the Page Information and copying the pageid from the URL part (e.g. confluence/pages/viewpage.action?pageId=43647697
) or use Copy Page ID (one of our Bookmarklets).
Get in action! Start by preparing the HTTP query string
querystring=$(urlencode -m id-list=12345678)"&"$(urlencode -m new-version=true)"&"$(urlencode -m comment=Changed using the WEB-API) echo $querystring
Explanation:
- The code above is written for bash
- The code is using the
urlencode
command provided by most Linux systems (/usr/bin/urlencode
) - The $() expressions start a subshell and evaluates
urlencode
command inline - Fill in the page id of the Confluence test page as value of
id-list
- Keep all spaces and do not add aditional spaces besides the spaces in the comment value
- The echo command allows you to validate the query string
Get in action! Apply the change to the test page
curl -n --header "Content-Type: application/json" \ -X PATCH "https://www.example.com/confluence/rest/projectdoc/1/document.json?"${querystring} \ --data-binary @document.json
Explanation:
- Change the URL to your Confluence server
- The file "
document.json
" contains the change to apply to the documents. This is the document you created in step 3
The name of the file in the file system must not contain the "@
" symbol! It is only necessary for cURL.
Check the result in Confluence regarding the change in the test page.
Now update and check the query string using all page Ids of the pages you intend to change.
Go back to Step 3 and copy the value of the property id-list.
Get in action! Insert the ids in the code below and check the new query string
querystring=$(urlencode -m id-list=128816586,128816588)"&"$(urlencode -m new-version=true)"&"$(urlencode -m comment=Changed using the WEB-API) echo $querystring
Check the query string.
Get in action! Last step: Apply the change to all pages selected by their ids
- This last line will apply the changes in the document
document.json
to all documents ofid-list
! - There is no rollback or undo!
- The result will list for each page, whether it was a success or a failure.
- There is no rollback when the change failed to alter one or some documents! The not failing documents will have the change applied to them.
Get in action! Execute curl code:
curl -n --header "Content-Type: application/json" \ -X PATCH "https://www.smartics.eu/confluence-test/rest/projectdoc/1/document.json?"${querystrng} \ --data-binary @document.json
- When some pages did not accept the change, but it succeeded for other pages: do not forget to remove those pages, which succeeded before you make a new attempt
- The recommendation is this: Analyse the error, reproduce it in a test environment (e.g. by copying some of these pages) and start with a new query to collect only those pages which did not succeed and try again
More Options to Change the Values
The Web API Extension provides some more options to change properties as to replace the values completely with some new Confluence macro code, like we did in steps 4 and 5.
The documentation Documents Service / PATCH is describing those position
property values, which can be used in the provided file document.json
.
So instead of using replace
as position
, which expects, that the property to change contains the full Confluence macro code as property value, we recommend to check, if one of the other positions
e.g. delete-values
, merge-values
or replace-values
provide a better usability for your use case.
- With
delete-values
it is possible to delete a special property value
In the example above we could have deleted the property valueType1
as a first step and then add the new valueType2
usingmerge-values
delete-values
just deletes the given value from the property, but keeps the macro information in place (even if it was the last value which has been deleted) - And
merge-values
checks if the new property value is already part of the property value; it does only add the value, if necessary
Conclusion
In this tip we had a look on how to conduct bulk changes for a property value in multiple projectdoc Documents by 4 easy steps:
- determine the documents you want to apply changes
- prepare the change
- apply the changes to one test document
- apply the changes to all documents
As mentioned in the introduction, the services provided by the Web API Extension can be integrated into your workflows in many ways. Integration into the user's browser can be done by bookmarklets or userscripts. From every information system capable of executing REST service requests and processing responses users can trigger changes on any side.
For more information please follow the resources links or get in touch!
Resources
For more information on topics discussed in this tip, please refer to the following resources.
- Web API Extension
- Add-on to extend projectdoc with an API to access on the web.
- projectdoc Toolbox
- Enhance your Documentation Experience ! The projectdoc Toolbox supports agile teams in writing documentation collaboratively
- cURL
- Command line tool and library for transferring data with URLs
- REST API Browser from Confluence
- Interactive API explorer for Atlassian products
- REST Login to Confluence with cURL
- To access Confluence via its REST API with cURL you typically need to authenticate. Learn how to login with cURL and avoid some common security pitfalls.
- Search Tips
- Tips on specifying search queries for Lucene. This also applies to projectdoc's query macros.
- Documents Service / PATCH
- Adds, removes, and applies changes to properties and sections of a projectdoc document.
- Copy Page ID
- Copies the page ID of the current Confluence page to the clipboard for later use.