Communardo Software GmbH, Kleiststraße 10 a, D-01129 Dresden
0800 1 255 255

Birthday list in Confluence

Who's birthday is the next? That's a frequently asked question in many companies. The answer is: "Let's use the "User Profiles plugin" for this! See here how it works


Who's bir­th­day is the next? That's a fre­quently asked ques­tion in many com­pa­nies. The ans­wer is: "Let's use the "User Profiles plugin" for this! See here how it works …

The User Profile Plugin offers a variety of func­tions to the Confluence pro­files to adapt them accord­ing to your own wis­hes and ideas. You can add addi­tio­nal pro­file ele­ments or syn­chro­nice any user data from an exter­nal user direc­tory into your Confluence. As a nice side effect this infor­ma­tion is also pro­vi­ded in the Confluence search. Since ver­sion 1.9 the User Profile Plugin pro­vi­des a REST API to retrieve the user data. And thats the way we get our list of birthdays!

What do we need?

Prerequisite for the func­tio­n­ing is an instal­led User Profile Plugin ver­sion 1.9 or hig­her. With this it is now pos­si­ble to create a new pro­file ele­ment by navi­ga­ting to the glo­bal admi­nis­tra­ti­ons "User Profile Configuration"-Section. Here we are going to create a new pro­file field with the name "Birthday". You should add a help text that the date of birth is expec­ted in the for­mat "" or TT.MM..

Now all users are able to insert their own bir­th­day into their profiles.


A user macro is holding the code

We are using a user macro to define a little bit of Javscript and CSS code. The macro its­elf can have any name you want. Place the fol­lowing code inside your macro:


## @noparams
<style type="text/css">
    .upp-birthday-list {
        margin-top: 10px;
    .upp-birthday-user .upp-pic {
		display: inline-block;
    .upp-birthday-user .upp-data {
		display: inline-block;
		vertical-align: top;
		margin-left: 10px;
		width: 130px;
		text-align: left;
	.upp-birthday-user  {
		display: inline-block;
		vertical-align: top;
		margin-right: 10px;
		margin-bottom: 10px;
		padding: 5px;
		border: 1px solid #ccc;
<h2>Birthday List</h2>
<div class="upp-birthday-list" > Search for birthdays... </div>
<script type="text/javascript">


		var queryStringArray = [];
		var actualDate = new Date();
		for(var i = -5; i <= 5; i++) {
			var newDate = new Date(actualDate.getFullYear(), actualDate.getMonth(), actualDate.getDate()+i); 
			var day = (newDate.getDate() < 10 ? "0" : "") + newDate.getDate();
			var month = ((newDate.getMonth() + 1) < 10 ? "0" : "") + (newDate.getMonth()+1);
			queryStringArray.push("Birthday:" + day + "." + month + "*");
		var queryString = queryStringArray.join(" OR ");
		jQuery.getJSON(contextPath+"/rest/searchv3/1.0/search?type=userinfo&queryString="+queryString ,function(result){
			if(result.results && result.results.length > 0) {
				jQuery.each(result.results, function(index, value){
					var match = value.url.match(/~(.*)\?/)[1];
                	if(match) {
                   		var userRawContainer = jQuery("<div class='upp-birthday-user' username='"+match+"'><div class='upp-pic'></div><div class='upp-data'></div></div>");
			} else {
				jQuery(".upp-birthday-list").html("No birthdays found :(");
        function initializeUppBirthdayUser(userRawContainer) {
            var userName = userRawContainer.attr("username");
            jQuery.getJSON(contextPath+"/rest/mobile/1.0/profile/"+userName, function(result){
				var userImg = jQuery("<img src='"+result.avatarUrl+"' >");
            	var userNameContainer = jQuery("<div>"+result.fullName+"</div>");
				getUppFieldValue(userName, "Birthday", userRawContainer.find(".upp-data"));
		 function getUppFieldValue(username, fieldKey, containerToAppendTo) {
 			jQuery.getJSON(contextPath+"/rest/communardo/upp/1.0/profileData/"+username+"?expand=profileData.profileElement", function(uppdata){
               jQuery.each(uppdata.profileData, function(uppindex, uppvalue) {
                    if(uppvalue.profileElement.defaultName == fieldKey) {
						var birthdayStampArray =".");
						var valueContainer = jQuery("<div>""</div>").hide();
						containerToAppendTo.closest(".upp-birthday-user").attr("birthdayforsort", (birthdayStampArray[1]+birthdayStampArray[0]));
		function sortBirthdayElements() {
			var uppBirthdayList = jQuery(".upp-birthday-list");
			var sortedItems = uppBirthdayList.find(".upp-birthday-user").sort(function(a, b) { 
				if(!a || !b || !jQuery(a).attr("birthdayforsort") || !jQuery(b).attr("birthdayforsort")) {
					return 0;
				return (jQuery(a).attr("birthdayforsort") < jQuery(b).attr("birthdayforsort") ? -1 : (jQuery(a).attr("birthdayforsort") > jQuery(b).attr("birthdayforsort") ? 1 : 0)); 


What exactly happens in the user macro?

The user macro its­elf is quite simple. First, a query is sent to Confluence via Javascript. This gives us all the users who had a bir­th­day in the last 5 days or have a bir­th­day wit­hin the next 5 days. Another query now asks for the exact birt­day of each found user. Once all users have been loa­ded, the macro is able finally sort the ent­ries by the date of birth.

15. Juli 2014

Pin It on Pinterest