Velocity loop through JSON - velocity

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

Related

How to create and access a multi level map in Velocity?

I want to create a dynamic map with multiple values for each entry, and then be able to run over that map and match up values with another list. Here is what I mean:
#set($map = {})
#foreach( $Item in $someQuery.getResults() )
#set( $day = "Monday") ## This would be a dynamic value.. just example here
#set( $startTimeHour = "8")
#set( $startTimeMinute = "00")
#set( $endTimeHour = "17")
#set( $endTimeMinute = "30")
## Now I need here to put this into a map...
$!map.put("${foreach.count}", "dayValue": $day, "startTimeHourValue": $startTimeHour, "startTimeMinuteValue": $startTimeMinute, "endTimeHourValue": $endTimeHour, "endTimeMinuteValue": $endTimeMinute)
#end
With this, I want to be able to do this in another for each loop
#foreach($newItem in $someList)
#if($newItem.DayValue IS IN MAP DAY VALUE $map.dayValue????)
## Print everything associated with this map entry
$map.dayValue
$map.startTimeHourValue
$map.startTimeMinuteValue
$map.endTimeHourValue
$map.endTimeMinuteValue
#end
#end
I am very new to velocity and have no Java knowledge, so any help would be greatly appreciated. Thanks!

Marketo, Velocity Scripting for Emails and templates

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} >

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