User macro accessing content properties?
Asked by Carsten Hilber:

I wrote a user macro to show values in a page that have been written to the content properties of the page. I have seen that the properties I can access within the template are not the same that I have been writing with the REST API, why is that?

writing the properties with REST:

<https://test.confluence.localdomain/rest/api/content/75333645/property> and the key/value in post (key: t-version, value: 1.2.3-SNAPSHOT)

check the properties with a get:

<https://test.confluence.localdomain/rest/api/content/75333645/property/> returns:

```
{"results":[{"id":"75333718","key":"t-version","value":"1.2.3-SNAPSHOT",...
```

So my rest call was successfull and my data is stored.

If I now access the content properties in the velocity template of the macro:

```
ID: $content.getIdAsString()

#foreach ( $item in $content.getProperties().asList() ) 
$item.getName() : $item.getStringValue() , 
#end
```

I get the following values in the page ID 75333645:

ID: 75333645 legacy.draft.parent.id : $item.getStringValue() , macro-count.note : 48-1 , macro-create-events-published-for-version : $item.getStringValue() , macro-count.user-macro : 48-2 , sync-rev : dummy-sync-rev , macroNames : note,content-properties-makro ,

Q1: What is up with that?

Q2: How do I get to the content properties that I set via REST?


Answers:
author: Bill Bailey
body: Hello [@Carsten Hilber](/t5/user/viewprofilepage/user-id/518706) , maybe a stupid question, but if the data is stored as key value pairs (per your REST call), are you using the right method to retrieve that data? When I have used a key-value map, I had to use the put and get methods.

Take a look in the example in the article I wrote that uses these methods: [Getting-Started-with-User-Macros-Writing-a-Wrapper-Macro](https://community.atlassian.com/t5/Confluence-articles/Getting-Started-with-User-Macros-Writing-a-Wrapper-Macro/ba-p/979571)

comments: author: Carsten Hilber
body: Hi Bill, thanks for the Answer. I tried to look over your macro, good stuff that you did there! But what you're writing about are page properties, not content properties. Maybe I misunderstood the API on that and though I use stuff that don't belong together, as you say.

The doc I used was this: <https://developer.atlassian.com/server/confluence/content-properties-in-the-rest-api/>

Anyway, I can always use jquery to access the rest endpoint to get the property I want, it's just not so elegant. for those who ask themselfes how you access the confluence REST API from a macro, here's some sample code:

```
## This makro renders content that jenkins put into content properties of the page
## @param property-key:title=property key|type=string|desc=Der Schl?ssel unter dem Jenkins den Wert ?bermittelt

## will be used in ajax call
#set($context='$')

<div style="display:block;">
<div style="display:inline-block;">$body</div>
<div style="display:inline-block;">&nbsp;<div>
<div style="display:inline-block;" id="$paramproperty-key" >No information posted yet for property $paramproperty-key</div>
</div>

<script type="text/javascript">
var url = "/rest/api/content/"+$content.getIdAsString()+"/property/$paramproperty-key"
AJS.${context}.ajax({
url: url,
type: "GET",
contentType: "application/json",
success: function(json){
document.getElementById('$paramproperty-key').textContent = json.value
}
});
</script>
```

it would just be nice to know how to get to these content-properties just by navigating over the injected velocity objects...

I will accept your answer without to know that because I really like your macro blog :-)


author: Bill Bailey
body: Thanks for the kind words.

The point I was trying to make is that you may need to use get and put methods as it appears that the content properies are stored as a key map (key-value pairs). So you would need to do something like

$content.properties.get($key)

For example

$content.properties.get("t-version")


author: Carsten Hilber
body: Ah, I see. I tried it, but had no luck.

The ContentProperties returned by $context do not have any methods for get

<https://docs.atlassian.com/ConfluenceServer/javadoc/7.15.0/com/atlassian/confluence/content/ContentProperties.html>

I'm pretty sure that the 'Rest' Content Properties and the properties returned by $content are different things.


author: Bill Bailey
body: Yeah, it can be frustrating at times. Not all objects are exposed to Velocity. And I have had to do a lot of research to figure out how to retrieve certain objects at times.


author: WW
body: I've been trying to figure out the ins and outs of content properties / metadata, and it can be quite confusing since there are **two separate kinds** , which Atlassian has **named the same**.

The **REST API** content properties are stored in the *content* (key as the *title* ) and *bodycontent* (value as Json) tables.

The **Java API** content properties are stored in the *contentproperties* table.

**They're completely different**.

So when you set the values with the REST API, you cannot retrieve the values with the Java API, which is essentially what you're trying to do in the user macro with Velocity.

You'd have to GET the data with the REST API if you POST the values with it.

How can you set the values with the Java API so that you can pull them with the Java API? If you figure that out, I'd like to know.


Tags: confluence-server

server