Forum Discussion

PerBonomi's avatar
10 years ago

Give users badges for solutions in specific boards

Thought I'd share this code to give users badges for getting solutions in specific boards. Can alos be fairly easily re-written to look for posts or replies, instead.

 

Feedback is welcome.

 

<#if !user.anonymous>
	<#assign boardLookIn = ["boardid1","boardid2"]/> <#-- Include all the board ids you want to look for -->
	<#assign brd = "${coreNode.id}"/> <#--  Check current board id -->
	<#if boardLookIn?seq_contains(brd) == true> <#--  Only continue if user is in one of the boards you want to look for (Avoid running the entire script on every page.) -->
		<#assign postsInBoard = rest("/users/id/${user.id}/posts/in/boards/id/${brd}/count").value?number/>
		<#if (postsInBoard >= 10)> <#--  Only continue if user has more than 10 posts in this board -->
			<#if brd == "board1"> <#-- check first board -->
				<#assign has_Sol_board1_10 = "false" /> <#--  Variable to check against user roles, call it anything you like -->
				<#assign has_Sol_board1_20 = "false" />
				<#assign has_Sol_board1_30 = "false" />
				<#assign has_Sol_board1_50 = "false" />
				<#assign has_Sol_board1_100 = "false" />
				<#assign has_Sol_board1_200 = "false" />
				<#assign selfRoles = restadmin("/users/self/roles").roles.role />
				<#list selfRoles as selfRole>
					<#if selfRole.name == "has_Sol_board1_10"><#assign has_Sol_board1_10 = "true" /></#if> <#-- start checking if user already has certain roles -->
					<#if selfRole.name == "has_Sol_board1_20"><#assign has_Sol_board1_20 = "true" /></#if>
					<#if selfRole.name == "has_Sol_board1_30"><#assign has_Sol_board1_30 = "true" /></#if>
					<#if selfRole.name == "has_Sol_board1_50"><#assign has_Sol_board1_50 = "true" /></#if>
					<#if selfRole.name == "has_Sol_board1_100"><#assign has_Sol_board1_100 = "true" /></#if>
					<#if selfRole.name == "has_Sol_board1_200"><#assign has_Sol_board1_200 = "true" /></#if>
				</#list>				
				<#assign x= rest("2.0","/search?q=" + "SELECT count(*) FROM messages WHERE is_solution = true AND author.id = '${user.id}' AND board.id = '${brd}'"?url) />
				<#assign userSolutions = x.data.count/>
				<#if (userSolutions >= 10)	&& has_Sol_board1_10 == "false">	<#assign result = restadmin("/roles/name/has_Sol_board1_10/users/add?role.user=id/${user.id}") /></#if> <#--  if user has required amount of solutions and doesn't already have the role, assign it now  -->
				<#if (userSolutions >= 20)	&& has_Sol_board1_20 == "false">	<#assign result = restadmin("/roles/name/has_Sol_board1_20/users/add?role.user=id/${user.id}") /></#if>
				<#if (userSolutions >= 30)	&& has_Sol_board1_30 == "false">	<#assign result = restadmin("/roles/name/has_Sol_board1_30/users/add?role.user=id/${user.id}") /></#if>
				<#if (userSolutions >= 50)	&& has_Sol_board1_50 == "false">	<#assign result = restadmin("/roles/name/has_Sol_board1_50/users/add?role.user=id/${user.id}") /></#if>
				<#if (userSolutions >= 100)	&& has_Sol_board1_100 == "false">	<#assign result = restadmin("/roles/name/has_Sol_board1_100/users/add?role.user=id/${user.id}") /></#if>
				<#if (userSolutions >= 200)	&& has_Sol_board1_200 == "false">	<#assign result = restadmin("/roles/name/has_Sol_board1_200/users/add?role.user=id/${user.id}") /></#if>
			</#if>
			<#if brd == "board2"> <#-- check second board; rinse, repeat -->
				<#assign has_Sol_board2_10 = "false" />
				<#assign has_Sol_board2_20 = "false" />
				<#assign has_Sol_board2_30 = "false" />
				<#assign has_Sol_board2_50 = "false" />
				<#assign has_Sol_board2_100 = "false" />
				<#assign has_Sol_board2_200 = "false" />
				<#assign selfRoles = restadmin("/users/self/roles").roles.role />
				<#list selfRoles as selfRole>
					<#if selfRole.name == "has_Sol_board2_10"><#assign has_Sol_board2_10 = "true" /></#if>
					<#if selfRole.name == "has_Sol_board2_20"><#assign has_Sol_board2_20 = "true" /></#if>
					<#if selfRole.name == "has_Sol_board2_30"><#assign has_Sol_board2_30 = "true" /></#if>
					<#if selfRole.name == "has_Sol_board2_50"><#assign has_Sol_board2_50 = "true" /></#if>
					<#if selfRole.name == "has_Sol_board2_100"><#assign has_Sol_board2 = "true" /></#if>
					<#if selfRole.name == "has_Sol_board2_200"><#assign has_Sol_board2 = "true" /></#if>
				</#list>				
				<#assign x= rest("2.0","/search?q=" + "SELECT count(*) FROM messages WHERE is_solution = true AND author.id = '${user.id}' AND board.id = '${brd}'"?url) />
				<#assign userSolutions = x.data.count/>
				<#if (userSolutions >= 10)	&& has_Sol_board2_10 == "false">	<#assign result = restadmin("/roles/name/has_Sol_board2_10/users/add?role.user=id/${user.id}") /></#if>
				<#if (userSolutions >= 20)	&& has_Sol_board2_20 == "false">	<#assign result = restadmin("/roles/name/has_Sol_board2_20/users/add?role.user=id/${user.id}") /></#if>
				<#if (userSolutions >= 30)	&& has_Sol_board2_30 == "false">	<#assign result = restadmin("/roles/name/has_Sol_board2_30/users/add?role.user=id/${user.id}") /></#if>
				<#if (userSolutions >= 50)	&& has_Sol_board2_50 == "false">	<#assign result = restadmin("/roles/name/has_Sol_board2_50/users/add?role.user=id/${user.id}") /></#if>
				<#if (userSolutions >= 100)	&& has_Sol_board2_100 == "false">	<#assign result = restadmin("/roles/name/has_Sol_board2_100/users/add?role.user=id/${user.id}") /></#if>
				<#if (userSolutions >= 200)	&& has_Sol_board2_200 == "false">	<#assign result = restadmin("/roles/name/has_Sol_board2_200/users/add?role.user=id/${user.id}") /></#if>
			</#if>
		</#if>
	</#if>
</#if>
  • PaoloT's avatar
    PaoloT
    Lithium Alumni (Retired)

    Hi PerBonomi

     

    thanks for sharing your code, very appreciated!

     

    I wonder, are you running this on the board page? I was thinking that it could be quite a few rest calls even though you have put some conditions. You could use the Activity Freemarker object so that this logic is only run immediately after the user has signed in for example.

    You could also create a function so that you don't repeat the code for each board you add.  Just throwing some ideas out there, I am sure others will be able to chime in as well with suggestions.

     

    Cheers,

    • PerBonomi's avatar
      PerBonomi
      Boss

      PaoloT wrote:

      Hi @PerBonomi

       

      thanks for sharing your code, very appreciated!

       

      I wonder, are you running this on the board page? I was thinking that it could be quite a few rest calls even though you have put some conditions. You could use the Activity Freemarker object so that this logic is only run immediately after the user has signed in for example.

      You could also create a function so that you don't repeat the code for each board you add.  Just throwing some ideas out there, I am sure others will be able to chime in as well with suggestions.

       

      Cheers,


      Thanks Paolo. I wasn't aware of the acitivy option; definitely worth incorporating that.

      I looked into using a function, for that reason, but then I'd end up using a kind of "hack" to create on the fly variables. According to the Freemarker documentation that isn't so good. But, if there's a cleaner way I'm all ears :)

  • Thanks for sharing the code. I'm also curious which page you added this component on. Header? Certain board/topic? or user profile?

     

    Also it feels like there are many unneccessary role assignment calls in here. e.g. if a user has 32 solutions on a board all the if clauses for the "lower" unlocks will trigger as well:

    <#if (userSolutions >= 10) && has_Sol_board2_10 == "false"> <#assign result = restadmin("/roles/name/has_Sol_board2_10/users/add?role.user=id/${user.id}") /></#if>

    No? Or will selfRole.name return correctly for user profiles with multiple roles?

    • PerBonomi's avatar
      PerBonomi
      Boss

      Claudius wrote:

      Thanks for sharing the code. I'm also curious which page you added this component on. Header? Certain board/topic? or user profile?

       

      Also it feels like there are many unneccessary role assignment calls in here. e.g. if a user has 32 solutions on a board all the if clauses for the "lower" unlocks will trigger as well:

      <#if (userSolutions >= 10) && has_Sol_board2_10 == "false"> <#assign result = restadmin("/roles/name/has_Sol_board2_10/users/add?role.user=id/${user.id}") /></#if>

      No? Or will selfRole.name return correctly for user profiles with multiple roles?


      I think the header is the only good place, to make sure it runs in all the relevant boards. It should be fairly low-bandwidth because there are no rest calls to check if it should run or not.

       

      On your second point, technically yes, but I think it's the only way to make sure users who've been around for a while still get the early badges. Could probably skip some of it if the script were live from the start of the community. From what I've seen selfRole.name works correctly.

       

      We also give users badges for reaching x total badges, so I want to be sure folks get the early badges too.

       

      Is that what you meant?