SOLVED

Email Script - construct variable names dynamically in velocity

Go to solution
Charles_THIERY
Level 3

Email Script - construct variable names dynamically in velocity

Hello

I wanted to know if there is an expression in order to do this:

#set( $TP = ["TP_A", "TP_B"])

#set( $TP_A = ["Button A", "https://www.wonderfulworld.com"])

#set( $TP_B = [@"Button B", "https://www.hellworld.com"])

#foreach( $asset in $TP )

     #if($lead.notengagedAssets.matches("(?i)(.*)(^|;)\s*${asset}\s*(;|$)(.*)") )

          <a href="${${asset}[1]}">${${asset}[0]}</a>

          ##I want to get the label out of the ${asset} variable and add the [...] to indicate which parameters to retreive.

     #end

#end

##The result expected should be:

          <a href="https://www.wonderfulworld.com">Button A</a>

          <a href="https://www.hellworld.com">Button B</a>

Is it possible? would it mess with the email click tracking of Marketo?

BR,

Charles

1 ACCEPTED SOLUTION

Accepted Solutions
SanfordWhiteman
Level 10 - Community Moderator

Re: Email Script - construct variable names dynamically in velocity

Hi again Charles,

That syntax isn't valid VTL -- you seem to be trying some kind of destructuring assignment from another language. But that part is easy to fix.

Unfortunately, you were right to wonder about click tracking. Marketo's Velocity install -- this is not true of a generic Velocity install, but then again Marketo is doing fancier stuff than most -- has undocumented rules against outputting multiple links from the same VTL $variable name. (This is separate from the stringent-but-documented rules about outputting a single link and keeping it trackable.) It's not that you can't loop, it's that the links will all end up the same (even though the link text will be different -- this literally pertains to the href only, which is where the tracking happens).

So, much as you would like (as best programming practices dictate) to iterate the assets and output the links, you have to declare a separate variable for each one. This means you have preallocate a maximum number of possible links. As a proponent of the ZOI principle I hate to encourage it. But at least it does work.

#set( $assetLinks = [

  {

  "innerText" : "Button A",

  "href" : "www.example.com/123"

  },

  {

  "innerText" : "Button B",

  "href" : "www.example.com/456"

  },

  {

  "innerText" : "Button C",

  "href" : "www.example.com/789"

  },

  {

  "innerText" : "Button D",

  "href" : "www.example.com/000"

  }

] )

#macro( listContains $haystack $needle $delim ) 

#if( $haystack.matches("(?i)(.*)(${delim}|^)\s*${needle}\s*(${delim}|$)(.*)") ) 

true## 

#else 

false## 

#end

#end

#set( $matchedLinks = [] )

#foreach( $assetLink in $assetLinks )

#if( "#listContains( $lead2.notengagedAssets $assetLink.href ';' )" == "true" ) 

#set( $res = $matchedLinks.add($assetLink) )

#end

#end

#if( !$matchedLinks.isEmpty() )

#set( $matchedLink = $matchedLinks.remove(0) )

#set( $href1 = $matchedLink.href )

<a href="https://${href1}">${matchedLink.innerText}</a>

#end

#if( !$matchedLinks.isEmpty() )

#set( $matchedLink = $matchedLinks.remove(0) )

#set( $href2 = $matchedLink.href )

<a href="https://${href2}">${matchedLink.innerText}</a>

#end

#if( !$matchedLinks.isEmpty() )

#set( $matchedLink = $matchedLinks.remove(0) )

#set( $href3 = $matchedLink.href )

<a href="https://${href3}">${matchedLink.innerText}</a>

#end

#if( !$matchedLinks.isEmpty() )

#set( $matchedLink = $matchedLinks.remove(0) )

#set( $href4 = $matchedLink.href )

<a href="https://${href4}">${matchedLink.innerText}</a>

#end

And so on, adding a $href{n} variable for each line.

One other thing: I'd caution against using ';' as a delimiter for URLs. After all, it is a valid character in a URL, though I understand you probably aren't expecting to have any such URLs to deal with. Delimiter collisions are some of my favorite worries.

View solution in original post

1 REPLY 1
SanfordWhiteman
Level 10 - Community Moderator

Re: Email Script - construct variable names dynamically in velocity

Hi again Charles,

That syntax isn't valid VTL -- you seem to be trying some kind of destructuring assignment from another language. But that part is easy to fix.

Unfortunately, you were right to wonder about click tracking. Marketo's Velocity install -- this is not true of a generic Velocity install, but then again Marketo is doing fancier stuff than most -- has undocumented rules against outputting multiple links from the same VTL $variable name. (This is separate from the stringent-but-documented rules about outputting a single link and keeping it trackable.) It's not that you can't loop, it's that the links will all end up the same (even though the link text will be different -- this literally pertains to the href only, which is where the tracking happens).

So, much as you would like (as best programming practices dictate) to iterate the assets and output the links, you have to declare a separate variable for each one. This means you have preallocate a maximum number of possible links. As a proponent of the ZOI principle I hate to encourage it. But at least it does work.

#set( $assetLinks = [

  {

  "innerText" : "Button A",

  "href" : "www.example.com/123"

  },

  {

  "innerText" : "Button B",

  "href" : "www.example.com/456"

  },

  {

  "innerText" : "Button C",

  "href" : "www.example.com/789"

  },

  {

  "innerText" : "Button D",

  "href" : "www.example.com/000"

  }

] )

#macro( listContains $haystack $needle $delim ) 

#if( $haystack.matches("(?i)(.*)(${delim}|^)\s*${needle}\s*(${delim}|$)(.*)") ) 

true## 

#else 

false## 

#end

#end

#set( $matchedLinks = [] )

#foreach( $assetLink in $assetLinks )

#if( "#listContains( $lead2.notengagedAssets $assetLink.href ';' )" == "true" ) 

#set( $res = $matchedLinks.add($assetLink) )

#end

#end

#if( !$matchedLinks.isEmpty() )

#set( $matchedLink = $matchedLinks.remove(0) )

#set( $href1 = $matchedLink.href )

<a href="https://${href1}">${matchedLink.innerText}</a>

#end

#if( !$matchedLinks.isEmpty() )

#set( $matchedLink = $matchedLinks.remove(0) )

#set( $href2 = $matchedLink.href )

<a href="https://${href2}">${matchedLink.innerText}</a>

#end

#if( !$matchedLinks.isEmpty() )

#set( $matchedLink = $matchedLinks.remove(0) )

#set( $href3 = $matchedLink.href )

<a href="https://${href3}">${matchedLink.innerText}</a>

#end

#if( !$matchedLinks.isEmpty() )

#set( $matchedLink = $matchedLinks.remove(0) )

#set( $href4 = $matchedLink.href )

<a href="https://${href4}">${matchedLink.innerText}</a>

#end

And so on, adding a $href{n} variable for each line.

One other thing: I'd caution against using ';' as a delimiter for URLs. After all, it is a valid character in a URL, though I understand you probably aren't expecting to have any such URLs to deal with. Delimiter collisions are some of my favorite worries.