12 Replies Latest reply on Aug 13, 2018 1:42 PM by Gally Articola

    Using multiple contains values in Velocity

    Gally Articola

      This is my first time using Velocity so apologies if it's an obvious answer. We need to populate based on multiple contains values in a single field, and have a default for anything that doesn't match but I'm not sure how best to write this out using Velocity. How would I write out this script?

       

      If Job Function contains "programmer" "engineer"

      Show: "Hello techie person"

       

      elseIf Job Function contains "marketer" "sales"
      Show: "Hello marketing person"

       

       

      elseIf Job Function doesn't contain any of those values

      Show: "Hello general person"

        • Re: Using multiple contains values in Velocity
          Sanford Whiteman

          Have you searched past threads on Velocity topics? There was one just the other day with a similar aim (the function is matches(), not contains ()).

            • Re: Using multiple contains values in Velocity
              Gally Articola

              Hi Sanford,

               

              Are you referring to this discussion? Velocity Script - value range

               

              It's helpful in showing how to set up a consolidated list of matches but I'm a little confused about how I can use this to:

              1. Target on incomplete values (so the lead's Job Function could be "programmer of nightmares" and they'd be included when I specify "programmer"

              2. How to target multiple incomplete values in the same string

              3. Use html as the shown content
              4. How to test the default value

               

              I'm not sure if this helps as an example, but here's what I'm attempting to do, and probably wrote out very badly

              #set( $textByjobFunction = {      
              "programmer" "engineer" : "<span style="color: #800080;">Hello techie person</span>",  
              "marketer" "sales" : "<span style="font-size: 16px; color: #B1309D;">Hello marketing person</span>",     
              "*" : "<span style="font-size: 16px; color: #99cc00;">Hello general person</span>"     
              } )     
              #foreach( $jobFunctionValue in $textByjobFunction.keySet() )     
              ## If we find a regex match for jobFunction we're done     
              #if($lead.jobFunction.matches("(?i)${jobFunctionValue}") )     
                  #set( $text = $htmlByjobFunction[$jobFunctionValue] )     
                  #break    
              #end     
              #end   
              $text
              
                • Re: Using multiple contains values in Velocity
                  Sanford Whiteman

                  Well, that isn't valid VTL to begin with so it will always throw an error, even before you get to any business logic.

                   

                  You also don't want to repeat yourself; the only thing different about those SPANs is the color so it should be factored out.

                   

                  Something more like this:

                   

                  #set( $outputByjobFunction = [        
                  {
                    "pattern" : "(?i).*\b(programmer|engineer)\b.*", 
                    "color" : "#800080",
                    "greeting" : "techie person"
                  },
                  {
                    "pattern" : "(?i).*\b(marketer|sales)\b.*", 
                    "color" : "#B1309D",
                    "greeting" : "marketing person"
                  },
                  {
                    "pattern" : ".*", 
                    "color" : "#99cc00",
                    "greeting" : "general person"
                  }
                  ] )       
                  #foreach( $outputSet in $outputByjobFunction )       
                  #if( $lead.jobFunction.matches($outputSet.pattern) )      
                      #set( $matchedOutputSet = $outputSet )       
                      #break      
                  #end       
                  #end
                  <span style="color: ${matchedOutputSet.color};">${matchedOutputSet.greeting}</span>
                  

                   

                  I did just write this on a plane so it may not be perfect, but it is the right pattern to follow.

                    • Re: Using multiple contains values in Velocity
                      Gally Articola

                      Ahhh got it! I'm running into issues with previewing, though. When I preview the email and view by person, I'm selecting leads I specifically set up for testing (so I know they don't exist in any other partitions), and of the 4 unique leads I set up, 2 (one in each pattern matches) show their dynamic content and the other 2 show the generic content.

                       

                      So this makes perfect sense, but how would I add a block of html for each variable? The team would want to add images, and they won't be consistent across each pattern. Is this the best way to write it out?

                       

                      #set( $outputByjobFunction = [          
                      {  
                        "pattern" : "(?i).*\b(programmer|engineer)\b.*",   
                        "color" : "#800080",  
                        "greeting" : "techie person", 
                        "image1" : "sm-black_i_50.gif",
                        "image2" : "sm-black_f_50.gif",
                        "image3" : "sm-black_t_50.gif"
                      },  
                      {  
                        "pattern" : "(?i).*\b(marketer|sales)\b.*",   
                        "color" : "#B1309D",  
                        "greeting" : "marketing person",
                        "image1" : "sm-rnd_fb_grey.png",
                        "image2" : "sm-rnd_i_grey.png"  
                      },  
                      {  
                        "pattern" : ".*",   
                        "color" : "#99cc00",  
                        "greeting" : "general person",
                        "image1" : "sm-square_li_100.gif",
                        "image2" : "sm-square_g_100.gif",
                        "image3" : "sm-square_fb_100.gif", 
                        "image4" : "sm-square_t_100.gif" 
                      }  
                      ] )         
                      #foreach( $outputSet in $outputByjobFunction )         
                      #if( $lead.jobFunction.matches($outputSet.pattern) )        
                          #set( $matchedOutputSet = $outputSet ) 
                          #set( $imagePath = "http://lp.accessintel.com/rs/881-ZTT-725/images/" )        
                          #break        
                      #end         
                      #end  
                      <span style="color: ${matchedOutputSet.color};">${matchedOutputSet.greeting}</span>  
                      
                      
                      <table width="60%" border="0" cellspacing="0" cellpadding="6">
                        <tbody>
                          <tr>
                            <td align="center"><img src="${imagePath}${matchedOutputSet.image1}" width="30"></td>
                            <td align="center"><img src="${imagePath}${matchedOutputSet.image2}" width="30"></td>
                            <td align="center"><img src="${imagePath}${matchedOutputSet.image3}" width="30"></td>
                            <td align="center"><img src="${imagePath}${matchedOutputSet.image4}" width="30"></td>
                          </tr>
                        </tbody>
                      </table>
                      
                        • Re: Using multiple contains values in Velocity
                          Sanford Whiteman

                          Ahhh got it! I'm running into issues with previewing, though. When I preview the email and view by person, I'm selecting leads I specifically set up for testing (so I know they don't exist in any other partitions), and of the 4 unique leads I set up, 2 (one in each pattern matches) show their dynamic content and the other 2 show the generic content.

                          Don't test with Preview-by-Leads, test with a static list and Preview-by-List (lesson from the master!). 

                           

                          If you still have confusion about why someone isn't qualifying you can always output $lead.jobFunction directly for debugging.

                           

                          So this makes perfect sense, but how would I add a block of html for each variable? The team would want to add images, and they won't be consistent across each pattern. Is this the best way to write it out?

                           

                          #foreach( $outputSet in $outputByjobFunction )  #if( $lead.jobFunction.matches($outputSet.pattern) )   #set( $matchedOutputSet = $outputSet )   #set( $imagePath = "http://lp.accessintel.com/rs/881-ZTT-725/images/" )   #break  #end  #end 

                          The $imagePath is the same for every lead here, so there's no need to set it over and over again. It's indeed a good idea to store it in a variable, just not reassigning the value unnecessarily.

                           

                          <table width="60%" border="0" cellspacing="0" cellpadding="6">  <tbody>  <tr>  <td align="center"><img src="${imagePath}${matchedOutputSet.image1}" width="30"></td>  <td align="center"><img src="${imagePath}${matchedOutputSet.image2}" width="30"></td>  <td align="center"><img src="${imagePath}${matchedOutputSet.image3}" width="30"></td>  <td align="center"><img src="${imagePath}${matchedOutputSet.image4}" width="30"></td>  </tr>  </tbody> </table>

                          If I'm reading your requirements correctly, this won't work b/c you have different numbers of images for each lead. In this case you need to put the images in a collection (list) not individual vars and #foreach over it.. I'll post some sample code later tonight that will get you started.

                            • Re: Using multiple contains values in Velocity
                              Gally Articola

                              Thank you! I keep wondering if it would be faster to set up individual email script tokens with the tables of each images (the team keeps complicating this with more formatting needs, size changes, adding text, links, etc), but I'm still figuring out how to best write this all out so I really appreciate the guidance!

                                • Re: Using multiple contains values in Velocity
                                  Sanford Whiteman
                                  #set( $imagePath = "http://lp.accessintel.com/rs/881-ZTT-725/images/" )          
                                  #set( $outputByjobFunction = [            
                                  {    
                                    "pattern" : "(?i).*\b(programmer|engineer)\b.*",     
                                    "color" : "#800080",    
                                    "greeting" : "techie person",   
                                    "images" : [
                                      "sm-black_i_50.gif",  
                                      "sm-black_f_50.gif",  
                                      "sm-black_t_50.gif"  
                                    ]
                                  },    
                                  {    
                                    "pattern" : "(?i).*\b(marketer|sales)\b.*",     
                                    "color" : "#B1309D",    
                                    "greeting" : "marketing person",  
                                    "images" : [
                                      "sm-rnd_fb_grey.png",  
                                      "sm-rnd_i_grey.png"    
                                    ]
                                  },    
                                  {    
                                    "pattern" : ".*",     
                                    "color" : "#99cc00",    
                                    "greeting" : "general person",  
                                    "images" : [
                                      "sm-square_li_100.gif",  
                                      "sm-square_g_100.gif",  
                                      "sm-square_fb_100.gif",   
                                      "sm-square_t_100.gif"   
                                    ]
                                  }    
                                  ] )           
                                  #foreach( $outputSet in $outputByjobFunction )           
                                  #if( $lead.jobFunction.matches($outputSet.pattern) )          
                                      #set( $matchedOutputSet = $outputSet )   
                                      #break          
                                  #end           
                                  #end    
                                  <span style="color: ${matchedOutputSet.color};">${matchedOutputSet.greeting}</span>    
                                    <table width="60%" border="0" cellspacing="0" cellpadding="6">  
                                    <tbody>  
                                      <tr>
                                      #foreach( $image in $matchedOutputSet.images )  
                                        <td align="center"><img src="${imagePath}${image}" width="30"></td>  
                                      #end
                                      </tr>  
                                    </tbody>  
                                  </table> 
                                  

                                  I keep wondering if it would be faster to set up individual email script tokens with the tables of each images (the team keeps complicating this with more formatting needs, size changes, adding text, links, etc)

                                  It's almost never better to repeat yourself, though at the same time you have to stop people from constantly changing the spec on you...

                                    • Re: Using multiple contains values in Velocity
                                      Gally Articola

                                      This is amazing, thank you! I'm running into a new issue now, with the script above, everything works perfectly. However, when I alter the script to target specific Company Names, and create a static list of test leads that I know have company names that match the keywords, I get the following error in my email preview (viewing by List, not person, as you recommended ):

                                       

                                      Cannot get email content-

                                      An error occurred when procesing the email Body!

                                      Encountered "}" near

                                       

                                       

                                        "pattern" : "(?i)(.*)(^|,)\s*energysolutions|energysource|mhf services|energy solutions\s*(,|$)(.*)",      

                                        "speaker" : "goodbye",    

                                      },     

                                      {     

                                        "pattern" : "(?i)(.*)(^|,)\s*nuclear regulatory comm|nrc|usnrc\s*(,|$)(.*)", 

                                       

                                       

                                      This is the velocity script token I'm using. I'm sure I'm missing something obvious:

                                      #set( $outputByCompany = [              
                                      {      
                                        "pattern" : "(?i).*\b(energysolutions|energysource|mhf services|energy solutions)\b.*",       
                                        "speaker" : "goodbye",     
                                      },      
                                      {      
                                        "pattern" : "(?i).*\b(nuclear regulatory comm|nrc|usnrc)\b.*",       
                                        "speaker" : "hello",    
                                      },      
                                      {      
                                        "pattern" : ".*",       
                                        "speaker" : "from ${lead.Company}",    
                                      }      
                                      ] )             
                                      #foreach( $outputSet in $outputByCompany )             
                                      #if( ${lead.Company}.matches($outputSet.pattern) )            
                                          #set( $matchedOutputSet = $outputSet )     
                                          #break            
                                      #end             
                                      #end      
                                      ${matchedOutputSet.speaker}