Scriptrunner WebPanel in Confluence with Data

Martin Müller January 27, 2021

What I want:

A simple anonymous "Page Hit Counter" for each confluence page, displayed right to the breadcrumbs.

What I achived:

An EventListener (PageViewEvent) counts pageviews and stores them in a custom variable "HitCount" for every page:

import com.atlassian.confluence.pages.Page
import com.atlassian.confluence.core.ContentPropertyManager
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.confluence.event.events.content.page.PageEvent
import org.apache.log4j.*

def log = Logger.getLogger("com.onresolve.scriptrunner.runner.HitCounter")
log.setLevel(Level.INFO)

def contentPropertyManager = ComponentLocator.getComponent(ContentPropertyManager)
def Pevent = event as PageEvent
def page = Pevent.getPage()

def HitCount = null

//Get Hit Counter from Page. If not availiable, set it to 1
if (!contentPropertyManager.getStringProperty(page, "HitCount")){
contentPropertyManager.setStringProperty(page, "HitCount", "0")
log.info "New HitCounter set for page " + page.title
}

//Raise HitCount
HitCount = contentPropertyManager.getStringProperty(page, "HitCount").toInteger() + 1
log.info "HitCounter raised for page " + page.title +" to " + HitCount

//Save HitCount
contentPropertyManager.setStringProperty(page, "HitCount", HitCount.toString())
log.info "HitCounter saved for page " + page.title

 The EventListener works (no failures) and I managed to display the results in a custom macro:

import com.atlassian.confluence.pages.Page
import com.atlassian.confluence.core.ContentPropertyManager
import com.atlassian.sal.api.component.ComponentLocator

def contentPropertyManager = ComponentLocator.getComponent(ContentPropertyManager)
def entity = context.getEntity()
if (entity instanceof Page) {
def page = entity as Page

if (!contentPropertyManager.getStringProperty(page, "HitCount")){
"1"
}
else {
contentPropertyManager.getStringProperty(page, "HitCount")
}
}

 What I need:

I want the HitCounter to be displayed in a web panel that is shown at atl.page.metadata.banner. When only writing a static string, the code works. But with the call of getHitCount(), the writer writes nothing. I'm new to java/groovy so please be kind ;)

The code of the webpanel:

import com.atlassian.confluence.pages.Page
import com.atlassian.confluence.core.ContentPropertyManager
import com.atlassian.sal.api.component.ComponentLocator

writer.write("<div style=\"padding: 5px 5px 5px 0;\">Page Views: " + getHitCount() + "</div>")

String getHitCount(){
def contentPropertyManager = ComponentLocator.getComponent(ContentPropertyManager)
def page = context.page as Page

if (!contentPropertyManager.getStringProperty(page, "HitCount")){
return "1"
}
else {
return contentPropertyManager.getStringProperty(page, "HitCount")
}
}

 

1 answer

1 accepted

Suggest an answer

Log in or Sign up to answer
0 votes
Answer accepted
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
January 28, 2021

I think it's because there is no "page" object in that context.

When I create a panel in that same context

writer.write("""<div style="padding: 5px 5px 5px 0;">Test Panel: ${context.keySet()}</div>""")

I see just "Dashboard Test Panel: [action]"

So the only object inside the atl.page.metadata.banner is the "action" object

Byt outputing context.action.getClass() I was able to find my way to 

https://docs.atlassian.com/ConfluenceServer/javadoc/6.15.9/index.html?com/atlassian/confluence/pages/Page.html

Where I found that we can get the current page.

writer.write("""<div style="padding: 5px 5px 5px 0;">Test Panel: ${context.page.id}</div>""")

This returned the page id.

So I think if you just change 

def page = context.page as Page

to 

def page = context.action.page as Page

It might work

Martin Müller January 28, 2021

Yes that's it. Awesome!

Thanks! :)

TAGS
AUG Leaders

Atlassian Community Events