Marketo, Velocity Scripting for Emails and templates - velocity

I'm new to scripting in Marketo, and I am looking for an example script for using an if/then statement in Marketo.
We have an online form that will ask different questions, one of them being gender, and I want to populate a picture in the email that gets sent. Essentially, I'm looking for something that will do this:
if gender = male then display xyz.male.gif
if gender = female then display xyz.female.gif
If someone has an example Apache Velocity script (I've never used, so go ahead and laugh) I would be greatly in your debt. I can replicate really well, I just can't figure out from the tutorials how to make foo = bar.... Thanks!

You'll want to use your conditional to create a variable containing the path of your image and then print it into your img tag (or wherever it needs to go). Something like this:
#if ( $lead.Gender = Male )
#set ( $image = "www.example.com/male.jpg" )
#else
#set ( $image = "www.example.com/female.jpg")
#end
<img src="${image}"></img>
There are some examples here as well:
DOCUMENTATION / Email Scripting

A litle more advanced example:
#if ( ${lead.MarketoSocialGender} == "Male" )
#set ( $image = "https://example.com/male.jpg" )
#elseif ( ${lead.MarketoSocialGender} == "Female" )
#set ( $image = "https://example.com/female.jpg" )
#else
#set ( $image = "https://example.com/other.jpg" )
#end
<img src="${image} >

Related

Velocity loop through JSON

I am using Velocity to try and loop through some JSON data I have in a field in Marketo. I have used the tutorial here to change the JSON into a Velocity Map but have an issue trying to loop through the data which is now a map.
#set( $items = ${abandonedBasket_cList} )
###if( $items.get(7).basketJSON.isEmpty() )
###set( $items.get(7).basketJSON = '[]' )
###end
#foreach ($item in $items)
#if( $foreach.last )
#set( $lastitem = $item.basketJSON )
#end
#end
#set( $ClientReferrals = '#set( $ClientReferrals = ' + $lastitem + ' ) ' )
#evaluate( $ClientReferrals )
${ClientReferrals[0].itemDesc} ## outputs "Season Pass Holders"
<br>
${ClientReferrals[1].customerID} ## outputs "jill#example2.com"
<br>
I have managed output values from the "map" when using a specific static index like in the example.
The bit I am stuck on is trying to get it to loop through each object using the foreach tool in Velocity as I don't know how to iterate the [index] key as part of the loop.
Update
I have tried to use the code suggested but there is nothing displaying.
#foreach($key in $ClientReferrals.keySet())
#set($item = $ClientReferrals[$key])
$item.itemDesc
${item.itemDesc}
$item
${item}
#end
If I output what $ClientReferrals looks like this is what I get. Does this look like a Hashmap to you?
[{id=29071940, itemDesc=1.33ct AA Tanzanite 9K Gold Earrings, itemImage=https://cdn.gemporia.com/images/products/300/NJPS19.jpg, itemQuantity=1, itemPrice=£151.00, customerID=1132399, basketURL=https://secure.gemporia.com/basket.aspx, isAuction=false, stock=10, dateAdded=2017-02-15}, {id=29071946, itemDesc=Size J to K AA Tanzanite & White Zircon 9K Gold Ring ATGW 1.08cts, itemImage=https://cdn.gemporia.com/images/products/300/OZVJ80.5.jpg, itemQuantity=1, itemPrice=£89.99, customerID=1132399, basketURL=https://secure.gemporia.com/basket.aspx, isAuction=true, stock=1, dateAdded=2017-02-15}]
If $ClientReferrals is a map, then you can do:
#foreach($key in $ClientReferrals.keySet())
#set($item = $ClientReferrals[$key])
...
#end
Items won't be sorted by key for an HashMap, they will for a TreeMap.
By the way, to get the last item of an array, you can do:
#set($last_index = $items.size() - 1)
#set($last = $items[$last_index])

Lucene Highlighter class: highlight different words in different colors

Probably most people reading the title who know a bit about Lucene won't need much further explanation. NB I use Jython but I think most Java users will understand the Java equivalent...
It's a classic thing to want to do: you have more than one term in your search string... in Lucene terms this returns a BooleanQuery. Then you use something like this code to highlight (NB I am a Lucene newbie, this is all closely tweaked from Net examples):
yellow_highlight = SimpleHTMLFormatter( '<b style="background-color:yellow">', '</b>' )
green_highlight = SimpleHTMLFormatter( '<b style="background-color:green">', '</b>' )
...
stream = FrenchAnalyzer( Version.LUCENE_46 ).tokenStream( "both", StringReader( both ) )
scorer = QueryScorer( fr_query, "both" )
fragmenter = SimpleSpanFragmenter(scorer)
highlighter = Highlighter( yellow_highlight, scorer )
highlighter.setTextFragmenter(fragmenter)
best_fragments = highlighter.getBestTextFragments( stream, both, True, 5 )
if best_fragments:
for best_frag in best_fragments:
print "=== best frag: %s, type %s" % ( best_frag, type( best_frag ))
html_text += "&bull %s<br>\n" % unicode( best_frag )
... and then the html_text is put in a JTextPane for example.
But how would you make the first word in your query highlight with a yellow background and the second word highlight with a green background? I have tried to understand the various classes in org.apache.lucene.search... to no avail. So my only way of learning was googling. I couldn't find any clues...
I asked this question four years ago... At the time I did manage to implement a solution using javax.swing.text.html.HTMLDocument. There's also the interface org.w3c.dom.html.HTMLDocument in the standard Java library. This way is hard work.
But for anyone interested there's a far simpler solution. Taking advantage of the fact that Lucene's SimpleHTMLFormatter returns about the simplest imaginable "marked up" piece of text: chosen words are highlighted with the HTML B tag. That's it. It's not even a "proper" HTML fragment, just a String with <B>s and </B>s in it.
A multi-word query generates a BooleanQuery... from which you can extract multiple TermQuerys by going booleanQuery.clauses() ... getQuery()
I'm working in Groovy. The colouring I want to apply is console codes, as per BASH (or Cygwin). Other types of colouring can be worked out on this model.
So you set up a map before to hold your "markup details":
def markupDetails = [:]
Then for each TermQuery, you call this, with the same text param each time, stipulating a different colour param for each term. NB I'm using Lucene 6.
def createHighlightAndAnalyseMarkup( TermQuery tq, String text, String colour ) {
def termQueryScorer = new QueryScorer( tq )
def termQueryHighlighter = new Highlighter( formatter, termQueryScorer )
TokenStream stream = TokenSources.getTokenStream( fieldName, null, text, analyser, -1 )
String[] frags = termQueryHighlighter.getBestFragments( stream, text, 999999 )
// not sure under what circs you get > 1 fragment...
assert frags.size() <= 1
// NB you don't always get all terms in all returned LDocuments...
if( frags.size() ) {
String highlightedFrag = frags[ 0 ]
Matcher boldTagMatcher = highlightedFrag =~ /<\/?B>/
def pos = 0
def previousEnd = 0
while( boldTagMatcher.find()) {
pos += boldTagMatcher.start() - previousEnd
previousEnd = boldTagMatcher.end()
markupDetails[ pos ] = boldTagMatcher.group() == '<B>'? colour : ConsoleColors.RESET
}
}
}
As I said, I wanted to colourise console output. The colour parameter in the method here is per the console colour codes as found here, for example. E.g. yellow is \033[033m. ConsoleColors.RESET is \033[0m and marks the place where each coloured bit of text stops.
... after you've finished doing this with all TermQuerys you will have a nice map telling you where individual colours begin and end. You work backwards from the end of the text so as to insert the "markup" at the right position in the String. NB here text is your original unmarked-up String:
markupDetails.sort().reverseEach{ pos, markup ->
String firstPart = text.substring( 0, pos )
String secondPart = text.substring( pos )
text = firstPart + markup + secondPart
}
... at the end of which text contains your marked-up String: print to console. Lovely.

construct variable names dynamically in velocity

I would like to know if it is possible to construct name of variable into velocity dynamically.
i.e. lets say I've 6 variables into velocity template [name1, name2, name3 .. name6] I would like to output them.
So I'm looking in something like:
#foreach ( $counter in [1..6] )
${name${counter}}
#end
is it possible somehow?
It is possible using the #evaluate directive:
#evaluate ('$name1')
#set ($d = '$')
#foreach ($i in [1..6])
#set ($varName = "${d}name${i}")
#evaluate($varName)
#end
You could construct a map and build the names of the keys to retrieve the values you want:
#set( $map = {"${name}1":'value1', "${name}2":'value2'} )
#foreach ( $counter in [1..6] )
#set( $key = "${name}$counter" )
$map.get(${key})
#end
Here is a trick to set velocity variable with dynamic name.
If you manage to tune velocity context beforehand in java code like this:
VelocityContext context = new VelocityContext(paramsMap);
context.put("all", paramsMap);
then it would be possible to define dynamic vars in template like this:
#set($dynamicDef = "varName=varValue")
#set($dynamicName = $dynamicDef.substring(0, $dynamicDef.indexOf('=')))
#set($dynamicValue = $dynamicDef.substring($dynamicDef.indexOf('=')).substring(1))
## create var with dynamic name
$all.put($dynamicName, $dynamicValue)
and use them later like this:
#if ($varName)
varName=$varName ## prints varName=varValue
#end

Dynamic variable different for every Wordpress post: how to declare in loop?

I need a wordpress loop that for every post checks a meta numeric variable previously assigned to each of the taxonomies of the post and returns the sum of these meta variables.
To do so, I think I need a dynamic variable name for the total. I mean something like:
variablerelatedtopost = metataxonomy1 + metataxonomy2 + ... + metataxonomyn
echo variablerelatedtopost
How can I do that? Is it possible to generate a dynamic numeric variable via loop? and HOW can I refer to it in a general way, without adressing it with its name?
Thanks everyone! And sorry for possible English mistakes :P
EDIT: I just realized the code by Alex is not what I wanted. I need a variable which changes name at every post and which value is always = 0. Is there a solution?
can you not just add a counter to your loop like this?
//Total should start # 0 before the loop
$total = 0;
// The Query
$the_query = new WP_Query($args);
// The Loop
while ( $the_query->have_posts() ) : $the_query->the_post();
$amount = get_post_meta($post->ID, 'the_meta_data_field', true);
$total = $total + $amount;
endwhile;
//echo total
echo $total;
I found the solution to my problem: an array which increases its lenght at every cicle of the loop. I know it's simple but since I'm just a beginner it took me a while to think about it. I post the code here so maybe it can help someone (and if you find bugs or have improvements, please tell me)
//Before the loop, empty array
$totale = array();
// WP Loop
while ( $loop->have_posts() ) : $loop->the_post();
$totale[] = 0;
$indice = (count($totale)) - 1;
// $termvariable was previously set up as a term meta value
if( has_term( 'numberofterm', 'nameoftaxonomy' ) ) {
$totale[$indice] = $termvariable + $totale[$indice];
}

What is the best way to access an array inside Velocity?

I have a Java array such as:
String[] arr = new String[] {"123","doc","projectReport.doc"};
In my opinion the natural way to access would be:
#set($att_id = $arr[0])
#set($att_type = $arr[1])
#set($att_name = $arr[2])
But that it is not working. I have come with this workaround. But it a bit too much code for such an easy task.
#set($counter = 0)
#foreach($el in $arr)
#if($counter==0)
#set($att_id = $el)
#elseif($counter==1)
#set($att_type = $el)
#elseif($counter==2)
#set($att_name = $el)
#end
#set($counter = $counter + 1)
#end
Is there any other way?
You can use use Velocity 1.6: for an array named $array one can simply do $array.get($index).
In the upcoming Velocity 1.7, one will be able to do $array[$index] (as well as $list[$index] and $map[$key]).
You could wrap the array in a List using Arrays.asList(T... a). The new List object is backed by the original array so it doesn't wastefully allocate a copy. Even changes made to the new List will propagate back to the array.
Then you can use $list.get(int index) to get your objects out in Velocity.
If you need to get just one or two objects from an array, you can also use Array.get(Object array, int index)
to get an item from an array.
String[] arr = new String[] {"123", "doc", "projectReport.doc"};
In my opinion the natural way to access would be:
#set($att_id = $arr[0])
#set($att_type = $arr[1])
#set($att_name = $arr[2])
The value for this can be get by using $array.get("arr", 1) because there is no direct way to get the value from array like $att_id = $arr[0] in velocity.
Hope it works :)
Velocity 1.6
$myarray.isEmpty()
$myarray.size()
$myarray.get(2)
$myarray.set(1, 'test')
http://velocity.apache.org/engine/1.7/user-guide.html
there is an implicit counter $velocityCount which starts with value 1 so you do not have to create your own counter.
Brian's answer is indeed correct, although you might like to know that upcoming Velocity 1.6 has direct support for arrays; see the Velocity documentation for more information.
I ended up using the ListTool from the velocity-tools.jar. It has methods to access an array's elements and also get its size.
I has the same question and it got answered on another thread
#set ( $Page = $additionalParams.get('Page') )
#set ( $Pages = [] )
#if ( $Page != $null && $Page != "" )
#foreach($i in $Page.split(";"))
$Pages.add($i)
#end
#end
Array indexing in Confluence / Velocity templates