Extracting Values from a Custom Object Field - Velocity Token | Community
Skip to main content
March 13, 2017
Solved

Extracting Values from a Custom Object Field - Velocity Token

  • March 13, 2017
  • 2 replies
  • 7086 views

Greetings,

I have the following custom object called 'ProductInterest' in our CRM, this object includes a number of values, one of which is productName. A client can have multiple products (ProductName). If I drag and drop the field to the token script area, it shows as ${ProductInterestList.get(0).ProductName}

I am trying to write a Velocity Script Token to display an image based on what Products (ProductName) they are a member of. Token name is {{my.image}} and in the email I am calling it something like this

<img src="{{my.image}}" alt="">

The Velocity Script Token:

#if( $ProductInterest.ProductName == 'product1' || $ProductInterest.ProductName == 'product2' || $ProductInterest.ProductName == 'product3' )

myurl.com/images/Banner1.jpg

#else

myurl.com/images/Banner2jpg

#end

This is not working, the result is always Banner2 (the #else image) when testing on a lead that has either product 1, 2 or 3 only... any idea's?

(I even tried

#if( $ProductInterest.ProductName == 'product1' )

#elseif( $ProductInterest.ProductName == 'product2' )

#elseif( $ProductInterest.ProductName == 'product3' )

http://info.lazardnet.com/rs/211-JCD-267/images/Banner factsheet EMD_II.jpg

#else

http://info.lazardnet.com/rs/211-JCD-267/images/Banner factsheet.jpg

#end)

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by SanfordWhiteman

Thanks again Greg..

Will do the research, atleast now I am on the right track, again appreciate the help...


Ed, I'd use an extensible approach like so:

## Set up your map of products to related asset(s)

#set( $assetsByProduct = {

  "product1|product2|product3" : {

    "banner" : "BannerA.jpg"

  },

  "product4|product5" : {

    "banner" : "BannerB.jpg"

  },

  "product6|product7|product8" : {

    "banner" : "BannerC.jpg"

  },

  "" : {

    "banner" : "DefaultBanner.gif"

  }

} )

##

## Start w/default asset set (empty key)

#set( $assets = $assetsByProduct[""] )

##

## Guard against bad inputs (null or empty object list)

#if( $ProductInterestList && !$ProductInterestList.isEmpty() )

    ##

    ## Loop backwards through objects (standard foreach is fwd only)

    #foreach( $idx in [$math.sub($ProductInterestList.size(),1)..0] )

        #set( $interest = $ProductInterestList[$idx] )

        #foreach( $assetSet in $assetsByProduct.keySet() )

            ##

            ## If we find a regex match for [map key,ProductName] we're done

            #if( $interest.ProductName.matches("(?i)${assetSet}") )

                #set( $assets = $assetsByProduct[$assetSet] )

                #break($foreach.parent)

            #end

        #end

    #end

#end

<img src="http://www.example.com/rs/${assets.banner}">

It's actually very simple logic, but Velocity is wordy (the same concept in JS would be half as long, for example there you have Array#reverse() while in VTL that doesn't exist as a built-in function).

The gist is:

  • set up a mapping object that pairs product(s) with their banner images; use a default key ("") for when there's no match
  • scan all the lead's ProductInterest objects -- from last to the first
  • as soon as you get a pattern match, that's where you get your banner

It's extensible because you can add any other ProductInterest-specific data you want -- not just the "banner" property, but any other data that goes with the product. The $assetsByProduct map could be in its own script token for modularity.

Note the code uses a naive ordering to loop backward through the custom objects by index. You might want to sort them by some other property.

Final note: I added tabs for visual clarity. You'll want to delete them from your token (whitespace in Velocity doesn't disappear on its own, you may recall from other posts).

2 replies

August 18, 2017

Hi Ed

I hope below scripting works.

#if( ${ProductInterestList.get(0).ProductName} == 'product1' || ${ProductInterestList.get(1).ProductName} == 'product2' || ${ProductInterestList.get(2).ProductName} == 'product3' )

myurl.com/images/Banner1.jpg

#else

myurl.com/images/Banner2jpg

#end

##Explanation:

${ProductInterestList.get(0).ProductName}

1) Here ProductName contain multiple values product1,product2 and product3.

2) get(0) defines the positions and sets 0,1,2,3 to the values product1,product2 and product3 as below.

get(0)-->product1

get(1)-->product2

get(2)-->product3

Regards,

Dixith

SanfordWhiteman
New Participant
August 18, 2017

The question's already answered by my code above.

Grégoire_Miche2
New Participant
March 13, 2017

Hi Ed,

ProductInterest is a multi record array, since by design there is a 1-N relationsgip between leads and ProductInterest.

Hence the notation ${ProductInterestList.get(0).ProductName} that returns the first occurence of Producs interest for the lead.

#if( ${ProductInterestList.get(0).ProductName} == 'product1' || ${ProductInterestList.get(0).ProductName} == 'product2' || ${ProductInterestList.get(0).ProductName} == 'product3' )

myurl.com/images/Banner1.jpg

#else

myurl.com/images/Banner2jpg

#end

You could also store ${ProductInterestList.get(0).ProductName} in a variable and test this variable

#set($ProductInterest = ProductInterestList.get(0).ProductName)

#if( $ProductInterest == 'product1' || $ProductInterest == 'product2' || $ProductInterest == 'product3' )

http://www.myurl.com/images/Banner1.jpg

#else

http://www.myurl.com/images/Banner2jpg

#end

Also, please remember that if you have more than 1 product interest for a lead, only the ten most recently updated objects of a type are loaded. The list is ordered from most to least recently updated record.

-Greg

March 13, 2017

Hi Greg,

Thank you for the prompt reply, I have tried

#set($ProductInterest = $ProductInterestList.get(0).ProductName)

#if( $ProductInterest == 'product1' || $ProductInterest == 'product2' || $ProductInterest == 'product3' )

http://www.myurl.com/images/Banner1.jpg

#else

http://www.myurl.com/images/Banner2jpg

#end

Still only returning the second Banner. I have double checked the lead I am testing has Product 1 and should receive Banner1

Grégoire_Miche2
New Participant
March 13, 2017

@Sanford Whiteman​

this is for you

-Greg