Forum Discussion

Han's avatar
Han
Ace
7 years ago

Add a separator if freemarker loop has more than one item

I am new to logic in freemarker and  having trouble adding a separator in a loop if there is more than one item.

My current code below is adding a separator, but it appears after my items;

 <#assign userTypeCount = 0>
  <#list restadmin("/users/id/${user.id?c}/roles").roles.role as role>
    <#assign userType += role.name >
    <#assign userTypeCount ++>
 
    <#-- only add separator if user has more than one role -->
    <#if (userTypeCount >1)>
      <#assign userType += ' | '>
     
    </#if>
  </#list>


I also tried to use the built in functionality of has_next and <sep> however this did not work either.  

Does anyone have any suggestions?

  • Han

    It would resolve you problem

    ${userType?keep_before_last("|")}

    I may create an issue if a user does not have any role but I think every user will have at least one role.  Right?

    Here is an updated version.  Here is the output https://prnt.sc/jsccwr

     <#assign userTypeCount = 0>
    <#assign userType = ""/>
      <#list restadmin("/users/id/${user.id}/roles").roles.role as role>
        <#assign userType += role.name >
        <#assign userTypeCount ++>
     
        <#-- only add separator if user has more than one role -->
          <#assign userType += ' | '>
      </#list>
    ${userType}
    ${userType?keep_before_last("|")}

7 Replies

  • Can you share the error screenshot. Also, try it with simple assignment instead += 

    <#assign userType = userType + ' | '>

     

  • Han's avatar
    Han
    Ace
    7 years ago

    VikasB I am not getting any errors. If I remove the += then I overwrite my variable with a pipe, which is not my intended out come. 

    I would like to have the user roles displayed with a | separator if it's needed. 

  • Han

    You need to initialize the "userType" initially. Like this  

    <#assign userType = ""/>

    Here is the corrected version. 

    Note: It would add pipe after every role except in between of first and second role. 

     <#assign userTypeCount = 0>
    <#assign userType = ""/>
      <#list restadmin("/users/id/${user.id}/roles").roles.role as role>
        <#assign userType += role.name >
        <#assign userTypeCount ++>
     
        <#-- only add separator if user has more than one role -->
        <#if (userTypeCount >1)>
          <#assign userType += ' | '>
         
        </#if>
      </#list>
    ${userType}

     You need to remove the <#if> condition If you want to add a pipe after the first role also. 

  • Han's avatar
    Han
    Ace
    7 years ago

    VikasB thanks for the reply.  I am defining the var already. I just left that piece of code out of my snippet above. 

    Currently what I am getting displayed for user with one role is: 
    "Contributor |" 

    If  they have two or more roles I get :
    "Administrator | Contributor |"

     

    My desired output for one role is 
    "Contributor"

    and for two would be:
    "Administrator | Contributor "


    I've played around with a few variations of my condition, with similar results. I can't quite figure out what is going on as this is fairly simple logic. 

  • Han

    It would resolve you problem

    ${userType?keep_before_last("|")}

    I may create an issue if a user does not have any role but I think every user will have at least one role.  Right?

    Here is an updated version.  Here is the output https://prnt.sc/jsccwr

     <#assign userTypeCount = 0>
    <#assign userType = ""/>
      <#list restadmin("/users/id/${user.id}/roles").roles.role as role>
        <#assign userType += role.name >
        <#assign userTypeCount ++>
     
        <#-- only add separator if user has more than one role -->
          <#assign userType += ' | '>
      </#list>
    ${userType}
    ${userType?keep_before_last("|")}
  • Han's avatar
    Han
    Ace
    7 years ago

    Thanks VikasB, that works perfectly! I was hoping there would be something easy to solve my issue.  

  • luk's avatar
    luk
    Boss
    7 years ago

    Han May I suggest a slightly more elegant solution? You can use a sequence and ?join(), feels more clean IMHO...

    <#assign userTypeCount = 0 /> <#-- what is this for? -->
    <#-- use a sequence (a.k.a. array) instead of a string -->
    <#assign userType = [] />
    
    <#list restadmin("/users/id/${user.id}/roles").roles.role as role>
        <#-- this is how you "update" a sequence/hash in FreeMarker -->
        <#assign userType = userType + [role.name] />
        <#assign userTypeCount ++>
    </#list>
    
    <#-- now just join it together with your desired separator...done! -->
    ${userType?join("|")}