Velocity email scripting - beginner's guide? | Community
Skip to main content
January 6, 2017
Solved

Velocity email scripting - beginner's guide?

  • January 6, 2017
  • 3 replies
  • 13535 views

Hi everyone!

I'm starting to add email scripts in my emails and I'm looking for a guide for beginners, if this exists somewhere. I understand that Velocity is based on Java and that a Java guide could maybe help as well.

I'm trying to display text based on the Postal Code's first character:

#if(${lead.PostalCode}.substring(0, 0) == "H")

  #set($city = "Montreal")

#elseif(${lead.PostalCode}.substring(0, 0) == "M")

  #set($city = "Toronto")

#else

  #set($city = "your awesome city")

#end

${city}

This is raising an error, so I'm guessing the substring shouldn't be used this way. Any help will be greatly appreciated.

Thomas

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

#if( $lead.PostalCode.startsWith("H") )

  #set( $city = "Montreal" )

#elseif( $lead.PostalCode.startsWith("M") )

  #set( $city = "Toronto" )

#else

  #set( $city = "your awesome city" )

#end

${city}

  • Don't bother with ${formal notation} in #set directives, where it isn't necessary, makes code harder to read, and can break stuff. You don't need {} here.
  • substring(0,0) means 0 characters starting from index 0. That's not going to match anything.
  • String objects have a startsWith() shortcut that returns a boolean, so you don't need to create a new string (which is what substring() does).

Also, think about moving to a collection-first approach as I describe here. With Velocity, organization is precious (it's not a particularly easy-to-read language, mostly because of the need to reduce whitespace).  So having all your "magic strings" at the top of a script is helpful. Like so:

#set( $pcInitialToCity_xref = {

  "H" : "Montreal",

  "M" : "Toronto",

  "" : "your awesome city"

} )

#set( $pcInitial = $lead.PostalCode.substring(0,1) )

#set( $city2 = $pcInitialToCity_xref[$pcInitial] )

#if( !$city2 )

  #set ( $city2 = $pcInitialToCity_xref[""] )## default

#end

${city2}

  • In this case, I do use substring() because I need that single-character string to do a property key lookup.

3 replies

February 6, 2017

Do you put the java script directly in the source code of the email you are working with?

SanfordWhiteman
New Participant
February 6, 2017

Not JavaScript: Velocity (VTL)! Very, very different.

As I mentioned on your other thread, VTL goes in a token. Then the token name goes in your email.

Luke_Wotton
New Participant
February 10, 2017

Sanford, awesome work.

Question - can you put tokens inside a script token?

Example.

If foo = bar

token = {{my.token1}}

else

token = {{my.token2}}

Or does Marketo not evaluate tokens inside tokens?

SanfordWhiteman
SanfordWhitemanAccepted solution
New Participant
January 6, 2017

#if( $lead.PostalCode.startsWith("H") )

  #set( $city = "Montreal" )

#elseif( $lead.PostalCode.startsWith("M") )

  #set( $city = "Toronto" )

#else

  #set( $city = "your awesome city" )

#end

${city}

  • Don't bother with ${formal notation} in #set directives, where it isn't necessary, makes code harder to read, and can break stuff. You don't need {} here.
  • substring(0,0) means 0 characters starting from index 0. That's not going to match anything.
  • String objects have a startsWith() shortcut that returns a boolean, so you don't need to create a new string (which is what substring() does).

Also, think about moving to a collection-first approach as I describe here. With Velocity, organization is precious (it's not a particularly easy-to-read language, mostly because of the need to reduce whitespace).  So having all your "magic strings" at the top of a script is helpful. Like so:

#set( $pcInitialToCity_xref = {

  "H" : "Montreal",

  "M" : "Toronto",

  "" : "your awesome city"

} )

#set( $pcInitial = $lead.PostalCode.substring(0,1) )

#set( $city2 = $pcInitialToCity_xref[$pcInitial] )

#if( !$city2 )

  #set ( $city2 = $pcInitialToCity_xref[""] )## default

#end

${city2}

  • In this case, I do use substring() because I need that single-character string to do a property key lookup.
January 6, 2017

Thanks Sanford, that was very useful.

I subscribed to your blog!

For Substring I was referring to the wrong language I guess:

String (Java Platform SE 7 )

Where the second parameter in fact is the last index, not the length. Anyway... wrong language

I agree for the collection management. The code snippet I gave only showed a part of the postal codes I will manage, so going with the collection is the right was to go indeed.

Can you show me in the official docs where they mention startsWith()? I'm ashamed I missed that.

Thanks

SanfordWhiteman
New Participant
January 6, 2017

Java String::substring() is being called, but the second index is exclusive. Thus in the particular case of (0,0) I was illustrating that you're never going to fetch any characters.

Technically it's "from index 0 to index 0, including index 0 but not including index 0," but this phrasing might make you think (since the order of operations within substring() is actually undocumented) that you'd still get the character at index 0.

SanfordWhiteman
New Participant
January 6, 2017

There's nothing more beginner-y than the official docs. There's also an old book, Mastering Jakarta Velocity, which is worth picking up, even if 66% of it is aimed at Java programmers (that is, people implementing Velocity into their Java projects, as opposed to mere "consumers" of existing Velocity installations, like Marketo users).

If you aren't following my blog posts on Velocity, you should.

I wouldn't say Velocity is "based on" Java (though you may be quoting the old me there!). It's written in Java, and as such can consume a subset of the Java native API. (On a good day, with the right project, I call it a "powerful subset"; on a bad day, I call it a "an embarrassingly small subset." It depends on what you're trying to do.)  

VTL is a standalone, lightweight template language that definitely isn't Java. But its separate syntax (# to start directives, for example) makes it easier for (some) Java syntax to be embedded directly in VTL without causing parsing errors.