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 …
The User Profile Plugin offers a variety of functions to the Confluence profiles to adapt them according to your own wishes and ideas. You can add additional profile elements or synchronize any user data from an external user directory into your Confluence. As a nice side effect, this information is also provided in the Confluence search. Since version 1.9 the User Profile Plugin provides a REST API to retrieve the user data. And that’s the way we get our list of birthdays!
What do we need?
Prerequisite for the functioning is an installed User Profile Plugin version 1.9 or higher. With this, it is now possible to create a new profile element by navigating to the global administrations “User Profile Configuration”-Section. Here we are going to create a new profile field with the name “Birthday”. You should add a help text that the date of birth is expected in the format “dd.mm.yyyy” or TT.MM..
Now all users are able to insert their own birthday 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 itself can have any name you want. Place the following 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; } </style> <h2>Birthday List</h2> <div class="upp-birthday-list" > Search for birthdays... </div> <script type="text/javascript"> jQuery(document).ready(function(){ 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(".upp-birthday-list").html(""); 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>"); jQuery(".upp-birthday-list").append(userRawContainer); initializeUppBirthdayUser(userRawContainer); } }); } 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+"' >"); userRawContainer.find(".upp-pic").append(userImg); var userNameContainer = jQuery("<div>"+result.fullName+"</div>"); userRawContainer.find(".upp-data").append(userNameContainer); 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 = uppvalue.data.split("."); var valueContainer = jQuery("<div>"+uppvalue.data+"</div>").hide(); containerToAppendTo.closest(".upp-birthday-user").attr("birthdayforsort", (birthdayStampArray[1]+birthdayStampArray[0])); containerToAppendTo.append(valueContainer); sortBirthdayElements(); valueContainer.fadeIn(); } }); }); } 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)); }); uppBirthdayList.find(".upp-birthday-user").remove(); uppBirthdayList.append(sortedItems); } }); </script>
What exactly happens in the user macro?
The user macro itself is quite simple. First, a query is sent to Confluence via Javascript. This gives us all the users who had a birthday in the last 5 days or have a birthday within the next 5 days. Another query now asks for the exact birthday of each found user. Once all users have been loaded, the macro is able finally to sort the entries by the date of birth.