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
Related
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])
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!
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} >
Can anyone tell me how to use dynamic variables in smarty foreach loop. I am trying to create a module in prestashop and m very close to get it done.
here's my code:
//file name index.php
foreach( $subCategories as $s )
{
$foo = intval($s['id_category']);
$k = new Category($foo);
$var1 = "subSubCategories.$foo";
$var1 = $k->getSubCategories(1);
$smarty->assign(array('foo'.$foo => $var1));
}
//file name:index.tpl
{assign var=foo value=$foo$cat}
//where $cat is a variable that counts the number of categories
{if isset($foo) AND $foo}
{foreach from=$foo item=subCategories name=homesubCategories}
<p>{$subCategories.name}</p>
{/foreach}
{else}
<p>{l s='test failed'}</p>
{/if}
I've exhausted all of my resources and knowledge and feeling quite helpless at this moment. so plz help me out.
I am trying to create dynamic variables ('foo'.$foo i.e. foo1, foo2, and so on) depending on the number of sub-categories. I think m successful up to this point. Now moving on to the tpl file, here I want to access the dynamically created variable (foo2, foo3 etc.) using foreach. Now if I am doing this: {assign var=foo value=$foo3} I succeed in fetching the values from this subcategory using the same foreach loop. But when I do this: {assign var=foo value=$foo$catx} (where $catx stores the values for category id) it fails. Please help.
I use such code in section loop (for Smarty 2):
{section name=buildings loop=7 start=1 step=1 max=7}
<tr>
{assign var=part_number value="part`$smarty.section.buildings.index`_number"}
<td class="number">
<input class="number xshort" name="part{$smarty.section.buildings.index}_number" value="{$data.$part_number}" type="text">
</td>
</tr>
{/section}
As you can see, there are a creation of dynamic variable part_number (see backticks in value block). And then, you can use it as value="{$data.$part_number}".
Your $smarty->assign() call is incorrect; you've only got one parameter being sent to it, but it needs two parameters (the variable name, followed by the value). Based on your template code (looping through variable $foo), your loop should be something like this in PHP:
//file name index.php
$subcats = array();
foreach($subCategories as $s) {
$foo = intval($s['id_category']);
$k = new Category($foo);
$subcats[$foo] => $k->getSubCategories(1);
}
$smarty->assign('foo', $subcats);
Then it also looks like you're not using the Smarty {foreach} quite properly either. You're declaring the name attribute, of the foreach loop, but then not using it properly. Assuming $k->getSubCategories(1) returns a string, the smarty code would just have to be:
{foreach from=$foo item=subCategories}<p>{$subCategories}</p>{/foreach}
If $k->getSubCategories(1) returns an array with a 'homesubCategories' element (which is what I think you're trying to get at with your Smarty code), you still don't need the 'name' value on the foreach. You'd then just do:
{foreach from=$foo item=subCategories}<p>{$subCategories.homesubCategories}</p>{/foreach}
With $foo = intval($s['id_category']); you defined $foo as an integer.
Then you concat the string with $smarty->assign(array('foo'.**$foo** => $var1));
Correct is:
$foo = $s['id_category'];
$smarty->assign(array('foo'.$foo => $var1));
Dynamically named variables are generally a very bad design choice, making everything much more difficult than it needs to be.
If you have a set of elements you need to loop over or index into, put them in an array; then you don't need to do any magic assignments, as you can use normal foreach loops or array key access:
//file name index.php
// Build the array first, then assign it to Smarty at the end
$foo_array = array();
foreach($subCategories as $s)
{
$foo = intval($s['id_category']);
$k = new Category($foo);
// This line is redundant as you over-write on the following line:
// $var1 = "subSubCategories.$foo";
$var1 = $k->getSubCategories(1);
$foo_array[ $foo ] = $var1;
}
// Assigning one variable, so just pass name and value to $smarty->assign()
$smarty->assign('foo_array', $foo_array);
//file name:index.tpl
{* Look for the entry in the outer array with key "$cat", then loop over it *}
{foreach from=$foo_array[$cat] item=subCategories}
<p>{$subCategories.name}</p>
{/foreach}
it's possible to call variable dynamically created in template with this statement:
if for example $index = 2
{$foo{$index}}
then this will call variable with name {$foo2}
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