SOLVED

Re: Using Velocity Script to Set Content based upon a score range

Go to solution
Anonymous
Not applicable

Hi All,

I would like to use velocity script to set content based upon score, for example > 1000 <2000 and >2000 < 3000 and > 3000 < 10000 etc.

I am familiar with the below script and would like to learn how to modify it to achieve the above.

#if (${lead.example} == "1")

Content Here

#end

Thanks in advance

Tags (1)
1 ACCEPTED SOLUTION
SanfordWhiteman
Level 10 - Community Moderator

The easy way, but which can get kind of wordy if you have a lot of conditions:

#if( $lead.LeadScore.isEmpty() )

#set( $lead.LeadScore = "0" )

#end

#set( $LeadScore = $convert.toInteger($lead.LeadScore) )

#if( $LeadScore >= 500 && $LeadScore < 600 )

is between 500 and 599 inclusive

#elseif( $LeadScore >= 600 && $LeadScore < 700)

is between 600 and 699 inclusive

#elseif( $LeadScore >= 700 && $LeadScore < 1000)

is between 700 and 999 inclusive

#end

The more robust way, which is easier to maintain with lots of conditions. In this case I'm assigning another variable a friendly name like "low" or "high" which you can use to decide output:

#if( $lead.LeadScore.isEmpty() )

#set( $lead.LeadScore = "0" )

#end

#set( $LeadScore = $convert.toInteger($lead.LeadScore) )

#set( $absmin = $field.in($LeadScore.class).MIN_VALUE )

#set( $absmax = $field.in($LeadScore.class).MAX_VALUE )

#set( $ScoreRanges = [

  { "name" : "negative", "minmax" : [$absmin,0] },

  { "name" : "x-low",    "minmax" : [0,500] },

  { "name" : "low",      "minmax" : [500,600] },

  { "name" : "med",      "minmax" : [600,700] },

  { "name" : "high",     "minmax" : [700,1000]},

  { "name" : "x-high",   "minmax" : [1000,$absmax] }

])

#foreach( $range in $ScoreRanges )

#if( $LeadScore >= $range.minmax[0] && $LeadScore < $range.minmax[1] )

#set( $LeadRange = $range.name )

#break

#end

#end

Your named range is ${LeadRange}

View solution in original post

8 REPLIES 8
Phillip_Wild
Level 10

Ah, I think I knew this one but was too slow Sanford Whiteman​!

I'm now starting to understand why your code is the way it is - Marketo's implementation of Velocity imports everything as a string, not as an integer as you'd expect. Strings all the way down, right?

SanfordWhiteman
Level 10 - Community Moderator

Marketo's implementation of Velocity imports everything as a string, not as an integer as you'd expect. Strings all the way down, right?

Right, fields on leads/contacts will be serialized as a string, with sometimes cumbersome results. Calling toInteger to get a real Integer isn't the worst of it, the way you have to match Booleans ("1" or "") and Dates (all the timezone stuff I was always write) is more annoying.

Fields on custom objects can be native Integers and Doubles. Still no Booleans or Dates, though.

Anonymous
Not applicable

Thanks Sanford Whiteman very much appreciated. I will have a go at implemtation.

SanfordWhiteman
Level 10 - Community Moderator

The easy way, but which can get kind of wordy if you have a lot of conditions:

#if( $lead.LeadScore.isEmpty() )

#set( $lead.LeadScore = "0" )

#end

#set( $LeadScore = $convert.toInteger($lead.LeadScore) )

#if( $LeadScore >= 500 && $LeadScore < 600 )

is between 500 and 599 inclusive

#elseif( $LeadScore >= 600 && $LeadScore < 700)

is between 600 and 699 inclusive

#elseif( $LeadScore >= 700 && $LeadScore < 1000)

is between 700 and 999 inclusive

#end

The more robust way, which is easier to maintain with lots of conditions. In this case I'm assigning another variable a friendly name like "low" or "high" which you can use to decide output:

#if( $lead.LeadScore.isEmpty() )

#set( $lead.LeadScore = "0" )

#end

#set( $LeadScore = $convert.toInteger($lead.LeadScore) )

#set( $absmin = $field.in($LeadScore.class).MIN_VALUE )

#set( $absmax = $field.in($LeadScore.class).MAX_VALUE )

#set( $ScoreRanges = [

  { "name" : "negative", "minmax" : [$absmin,0] },

  { "name" : "x-low",    "minmax" : [0,500] },

  { "name" : "low",      "minmax" : [500,600] },

  { "name" : "med",      "minmax" : [600,700] },

  { "name" : "high",     "minmax" : [700,1000]},

  { "name" : "x-high",   "minmax" : [1000,$absmax] }

])

#foreach( $range in $ScoreRanges )

#if( $LeadScore >= $range.minmax[0] && $LeadScore < $range.minmax[1] )

#set( $LeadRange = $range.name )

#break

#end

#end

Your named range is ${LeadRange}

Anonymous
Not applicable

Hi Sanford,

I am gettign the following error when approving the asset:

Validation Error approving 2018-02-15-Consultant Incentive Velocity.EM-01-Submission Required — 

An error occurred when procesing the email Rendered_Email_Velocity_Error_Area_?!

Invocation of method 'toInteger' in class org.apache.velocity.tools.generic.ConversionTool threw exception java.lang.NullPointerException near

pastedImage_1.png

SanfordWhiteman
Level 10 - Community Moderator

If the score is nullable, add this at the very top:

#if( $lead.monthlyPV.isEmpty() )

#set( $lead.monthlyPV = "0" )

#end

Anonymous
Not applicable

Works a treat, so appreciated

SanfordWhiteman
Level 10 - Community Moderator

I was just diving (for the nteenth time) into Velocity's rather strange null handling and discovered this shorter method to skip the pre-check:

#set( $LeadScore = $convert.toIntegers($lead.LeadScore)[0] )

(in place of $convert.toInteger)

It's a bit quirky and in a way shouldn't work (toIntegers is ostensibly toInteger over a collection) but good to know.