How to add labels to confluence page via user macro?
Asked by Michael Rosenberger:

Before Confluence 7.1.0 we used the following, to automatically add labels in a user macro:

```
#set($labelManager=$containerContext.getComponent('labelManager'))
```

```
#set($success = ${content.labelUtil.addLabel('label-text', $action.labelManager, $content)})
```

This does not longer work with the update to Confluence 7.1.0. There seems to be no label manager anymore.

How to programatically set labels via user macro in Confluence 7.1.0?


Answers:
author: Sven Schatter _Lively Apps_
body: Hey [@Michael Rosenberger](/t5/user/viewprofilepage/user-id/3644277),

the "com.atlassian.confluence.labels.LabelManager#addLabel(com.atlassian.confluence.core.ContentEntityObject;com.atlassian.confluence.labels.Label;) int" method is one of [the deprecated methods that have been removed with Confluence 7](https://confluence.atlassian.com/doc/deprecated-code-paths-removed-in-7-0-967879993.html).

[From looking at the Java docs it seems like you'll need to use the createLabel() method instead.](https://docs.atlassian.com/ConfluenceServer/javadoc/7.1.0/com/atlassian/confluence/labels/LabelManager.html#createLabel-com.atlassian.confluence.labels.Label-) However, since this method expects to be passed an object of the type Label I'm not sure whether it is feasible to use this API in a user macro.

Cheers,  
Sven

comments: author: Michael Rosenberger
body: Hey,

thank you for your helpful replay. Unfortunately I am still not able to use the labelManager in the user macro. I think the problem is, that it not gets instantiated correctly.

I created a test macro with the following code. It does not remove the labels of the page where it is inserted. I first tired to add a label, but with no luck. No I used the removeAllLabels()-Method to test, but it also does not work.

```
#set($containerManagerClass=$action.class.forName('com.atlassian.spring.container.ContainerManager'))
#set($getInstanceMethod=$containerManagerClass.getDeclaredMethod('getInstance',null))
#set($containerManager=$getInstanceMethod.invoke(null,null))
#set($containerContext=$containerManager.containerContext)
#set($labelManager=$containerContext.getComponent('labelManager'))


#set($success = $labelManager.removeAllLabels($content))
```

How to initialize and use the labelManager correctly?


author: Sven Schatter _Lively Apps_
body: Sorry, no idea. I think you should probably [write an actual Java macro](https://developer.atlassian.com/server/confluence/writing-macros/) and let Confluence inject the LabelManager properly into your Macro class. This would be a lot easier and more flexible than trying to poke around with reflection inside a user macro.

Cheers


author: Matt Walsh
body: Did you ever get something working, [@Michael Rosenberger](/t5/user/viewprofilepage/user-id/3644277) ? Struggling w/ the exact same problem.

comments: author: Michael Rosenberger
body: Hi Matt,

we did not manage to get it to work with a user-macro only. So we actually wrote a Java Macro that does the job.

Cheers

Michael


author: Matt Walsh
body: Oh nice. I actually started exploring a JS solution before I looked into the user macro approach! Any chance you might share what you came up with?


author: Matt Walsh
body: (FWIW, using this JS, I was able to add labels to 'this' page - but not children pages)

```
<script type="text/javascript">

//=============================
AJS.$(window).load( function () {

var children = $('.plugin_pagetree_children_span');
var projectID = AJS.params.pageId;
var childId;

for(let i=0; i<children.length; i++){

//IDs are stored like this by pagetree macro: "childrenspan154443288-0"
//so gotta extract the "154443288" part
childId = children.get(i).id.substr(12,8);

alert("i=" + i + " id=" + childId );

AJS.Labels.addLabel("projectId" + AJS.params.pageId, AJS.params.pageId, AJS.params.contentType);
//AJS.Labels.addLabel("AA", childId, AJS.params.contentType);

//TODO: figure out why ^^^ won't allow me add a label to a different page? 

}




});



</script>
```


author: Michael Rosenberger
body: Hi Matt,

unfortunately I'm currently not able to publish our code because it is part of other internal stuff. If we decide to publish it, I will you update here. But this can take time...

Regards

Michael


author: Richard George
body: Hi Matt, this works fine for me, as I only need to add a label to the current page. Is there any documentation related to this? Also, any ideas how I might also delete a label?


author: Matt Walsh
body: I haven't found anything helpful sadly - most of my dev has been reverse engineering and exploring in browsers' debug tools (e.g. hit F12, then in the console, type AJS and follow the auto-complete train)

As for removing, this method should work, but I haven't tried it yet and don't have a good example for you: AJS.Labels.removeLabel()


author: Richard George
body: I tried that, but couldn't get it to work. I ended up with:

```
#set($D='$')
<script>
AJS.toInit(function(){
AJS.${D}.post(contextPath+'/json/removelabelactivity.action', {'entityIdString': '$content.id', 'labelIdString': "$paramLabel", 'atl_token': AJS.$('#atlassian-token').attr('content')});
AJS.$('ul.label-list li:contains("$paramLabel")').remove();
});
</script>
```

based on [https://community.atlassian.com/t5/Answers-Developer-Questions/Remove-labels-on-current-page-in-Confluence/qaq-p/464222](https://community.atlassian.com/t5/Answers-Developer-Questions/Remove-labels-on-current-page-in-Confluence/qaq-p/464222 "this post")

I can't help feeling that this should be simpler, but the above works.


author: Matt Walsh
body: I got it working.. here's a script that adds a label based on a parameter in the Page Properties table. It also removes old labels, so if you update the 'project key', the labels get updated accordingly:

```
[Page Properties Macro]
 ____________________
| prop 1      | x    |
| prop 2      | y    |
| Project Key | test |
```

```
[HTML Macro]

<script type="text/javascript">


//=============================
//AJS.$(window).load( function () { 
AJS.$(document).ready( function () {

var printMe = "Removed Keys:";
var prefix = "pkey-";
var keyName = "Project Key"; //hardwire to match page properties

// Find project key in page properties
var row = AJS.$('.plugin-tabmeta-details table th:contains("Project Key")').parent();

var newKey = AJS.$('td', row).text();
var newKeyLabel = "pkey-"+ newKey;

//Look through labels and remove old project keys
var labels = $('.aui-label-split-main');
for( var i = 0; i < labels.length; i++ ){
    //look for labels starting with 'prefix'
    if( labels[i].innerHTML.search(prefix) == 0 ) {
        //if doesn't match new/current key, remove it
        if(labels[i].innerHTML.search(newKeyLabel)) {
            AJS.Labels.removeLabel( $(labels[i]).closest("li") , AJS.params.pageId, AJS.params.contentType);
            printMe = printMe + " " +labels[i].innerHTML
        } 
    }
}

//Add newKeyLabel
AJS.Labels.addLabel(newKeyLabel, AJS.params.pageId, AJS.params.contentType);

//display what we found
document.getElementById("pageIdDisplayer").innerHTML = printMe;

});

</script>

<div style="text-align:right; font-size:x-small;" id=pageIdDisplayer></div>
```


author: Matthias Schouten
body: No Idea if this is still needed, but you could use

#set( $labelManager = $action.getLabelManager())

to get the labelmanager for a user macro

$action is the ConfluenceActionSupport, which is provided within the velocity templates by confluence (<https://developer.atlassian.com/server/confluence/confluence-objects-accessible-from-velocity/>), and holds a labelManager object (<https://docs.atlassian.com/ConfluenceServer/javadoc/7.11.1/com/atlassian/confluence/core/ConfluenceActionSupport.html>)


Tags: label

user-macro