SOLVED

Extracting Values from a Custom Object Field - Velocity Token

Go to solution
Anonymous
Not applicable

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}

productinterest.png

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)

1 ACCEPTED SOLUTION
SanfordWhiteman
Level 10 - Community Moderator

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).

View solution in original post

12 REPLIES 12