I have imported a list of records to custom objects which contains data based on user visits in the website. By using this list trying to create email in Marketo. From CO list, selecting only recent visit of the product. In the given list, have product name, image, URL and recent visit date.
Problem- I have created three velocity script and sorting the list based on recent visit date. But, in email output is display incorrect.
Below three velocity script used for sorting the product name, image and URL.
Script-1
<html>
<body>
<table>
## start product image select
<tbody>
#set( $DEFAULT_Product = "No item in list." )
<tr>
#if( $pro_cList.isEmpty() )
#set( $outputItemimage = $DEFAULT_Product )
#else
#foreach( $pro_c in $sorter.sort($pro_cList, "date:desc") )
#if( !$display.alt($pro_cList["productImage"],"").isEmpty() )
#set( $outputItemimage = $pro_c["productImage"] )
#break
#end
#end
#set( $outputItemimage = $display.alt($outputItemimage, $DEFAULT_Product) )
#end
<td>
<img width="189" align="right" src="${outputItemimage}" border="0"/>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Script-2
<html>
<body>
<table>
## start product name select
<tbody>
#set( $DEFAULT_Product = "No item in list." )
<tr>
#if( $pro_cList.isEmpty() )
#set( $outputName = $DEFAULT_Product )
#else
#foreach( $pro_c in $sorter.sort($pro_cList, "date:desc") )
#if( !$display.alt($pro_cList["productName"],"").isEmpty() )
#set( $outputName = $pro_c["productName"] )
#break
#end
#end
#set( $outputName = $display.alt($outputName, $DEFAULT_Product) )
#end
<td>
${outputName}
</td>
</tr>
</tbody>
</table>
</body>
</html>
Script-3
<html>
<body>
<table>
## start product URL select
<tbody>
#set( $DEFAULT_Product = "No item in list." )
<tr>
#if( $pro_cList.isEmpty() )
#set( $outputItemCTA = $DEFAULT_Product )
#else
#foreach( $pro_c in $sorter.sort($pro_cList, "date:desc") )
#if( !$display.alt($pro_cList["productCTA"],"").isEmpty() )
#set( $outputItemCTA = $pro_c["productCTA"] )
#break
#end
#end
#set( $outputItemCTA = $display.alt($outputItemCTA, $DEFAULT_Product) )
#end
<td>
<a href="${outputItemCTA}">Check out</a>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Solved! Go to Solution.
This line:
#if( !$display.alt($pro_cList["productName"],"").isEmpty() )
Should be:
#if( !$display.alt($pro_c["productName"],"").isEmpty() )
Remember, when you're iterating over the items ($pro_c) in the list, you want to test the item, not the whole list.
Hi Jayant,
This seems like an overly wordy (and thus fragile) way to do this — it could easily be a single token with a #macro since the logic is the same other than the field name.
Beyond that, I'd need to see a dump of all of the data from the list. Chances are, for the fields that are outputting the default value, you don't have them checked off in the tree in Script Editor.
Hi San,
Before creating macro, I want to fetch the data for each field correctly. So, I am not able to find checked off condition for the script. Can you please suggest more in this?
Not sure I understand what you're saying here. When I say "checked off" I mean in the tree (of Lead and Object fields) on the right-hand-side of Script Editor.
I have already selected that one but not sure why it is evaluating only default output this is the worry part and I am not starting macro unless I am sure that I can get output individually correct.
Please show a screenshot of the Script Editor tree with the checkboxes checked for all the fields.
If you want to check to see if something has a non-null value (including an empty String, which is a value) just output that ${lead.field}. If you've failed to check off the field, you'll see the literal VTL code, since that's what Velocity prints if the value is null.
I am selecting CO list tree. am I missing anything?
I see 3 fields, sure, though what their Velocity property names are isn't clear.
Run this standard CO debugging code:
#set( $coList = $pro_cList )
#foreach( $record in $coList )
#foreach( $kv in $record.entrySet() )
${kv.getKey()} ${display.alt($kv.getValue().class,"")} ${display.alt($kv.getValue(),"null")}
#end
#end
In the given code,
1. kv and record will be replaced with any property?
2. This code need to add in velocity script in starting
Nope, nothing to replace.
Just put this exact at the top of your token to get debug output.
I have added the code in three ways
1. Full code at top after debug no change in previous email design.
2. Both end statement at last after debug nothing display.
3. Putting both end statement before output the ${outputName} and got below design
I'm not sure you're putting the code in the right place.
If you put that code in a Velocity token (in Script Editor) it'll give you a full debug dump of all the fields in the given list, with their names, values (or null) and datatypes.
This is the one script product name where I added the code at the top.
<html>
<body>
<table>
#set( $coList = $pro_cList )
#foreach( $record in $coList )
#foreach( $kv in $record.entrySet() )
{kv.getKey()} ${display.alt($kv.getValue().class,"")} ${display.alt($kv.getValue(),"null")}
#end
#end
## start product name select
<tbody>
#set( $DEFAULT_Product = "No item in list." )
<tr>
#if( $pro_cList.isEmpty() )
#set( $outputName = $DEFAULT_Product )
#else
#foreach( $pro_c in $sorter.sort($pro_cList, "date:desc") )
#if( !$display.alt($pro_cList["productName"],"").isEmpty() )
#set( $outputName = $pro_c["productName"] )
#break
#end
#end
#set( $outputName = $display.alt($outputName, $DEFAULT_Product) )
#end
<td>
${outputName}
</td>
</tr>
</tbody>
</table>
</body>
</html>
is code placement is incorrect?
It's very surprising to me that you're outputting the entire email from a single Velocity token. That's not usually — well, basically, it's never done.
Please reduce the "testing surface" so that you're only outputting the product list (using my debug code) from VTL. Don't mix in anything else, put everything else in the template.
I am using only the debug code and removed everything from VTL.
#set( $coList = $pro_cList )
#foreach( $record in $coList )
#foreach( $kv in $record.entrySet() )
{kv.getKey()} ${display.alt($kv.getValue().class,"")} ${display.alt($kv.getValue(),"null")}
#end
#end
${coList}
In the template, I am using {{my.VTL}} to debug it now. is it ok now or need to add code more?
That's seems like the right start.
So what's in the output?
{kv.getKey()} class java.lang.String 2020-03-23 08:20:02 {kv.getKey()} class java.lang.String 4 {kv.getKey()} class java.lang.String https://www.mdg.co.in/product/item4.html {kv.getKey()} class java.lang.String b1c1c49a-1545-3c38-a421-d3af748ac5c1 {kv.getKey()} class java.lang.String http://ta-sj29.marketo.com/rs/717-ICG-368/images/item4.png {kv.getKey()} class java.lang.String item3 {kv.getKey()} class java.lang.String 2020-04-24 08:20:02 {kv.getKey()} class java.lang.String 5 {kv.getKey()} class java.lang.String https://www.mdg.co.in/product/item6.html {kv.getKey()} class java.lang.String b1c1c49a-1545-3c38-a421-d3af748ac5c1 {kv.getKey()} class java.lang.String http://ta-sj29.marketo.com/rs/717-ICG-368/images/item6.png {kv.getKey()} class java.lang.String item4 {kv.getKey()} class java.lang.String 2020-05-20 08:20:02 {kv.getKey()} class java.lang.String 6 {kv.getKey()} class java.lang.String https://www.mdg.co.in/product/item5.html {kv.getKey()} class java.lang.String b1c1c49a-1545-3c38-a421-d3af748ac5c1 {kv.getKey()} class java.lang.String http://ta-sj29.marketo.com/rs/717-ICG-368/images/item5.png {kv.getKey()} class java.lang.String item5 [{date=2020-03-23 08:20:02, leadID=4, productCTA=https://www.mdg.co.in/product/item4.html, productID=b1c1c49a-1545-3c38-a421-d3af748ac5c1, productImage=http://ta-sj29.marketo.com/rs/717-ICG-368/images/item4.png, productName=item3}, {date=2020-04-24 08:20:02, leadID=5, productCTA=https://www.mdg.co.in/product/item6.html, productID=b1c1c49a-1545-3c38-a421-d3af748ac5c1, productImage=http://ta-sj29.marketo.com/rs/717-ICG-368/images/item6.png, productName=item4}, {date=2020-05-20 08:20:02, leadID=6, productCTA=https://www.mdg.co.in/product/item5.html, productID=b1c1c49a-1545-3c38-a421-d3af748ac5c1, productImage=http://ta-sj29.marketo.com/rs/717-ICG-368/images/item5.png, productName=item5}]
You have a typo.
{kv.getKey()}
is supposed to be
${kv.getKey()}
Also, can you please do this in the Text-only version of the email so the line breaks are preserved? 🙂 Kind of impossible to read otherwise.
date class java.lang.String 2020-03-20 08:20:02
leadID class java.lang.String 1
productCTA class java.lang.String https://www.mdg.co.in/product/item.html
productID class java.lang.String 059130d0-b9a5-4691-9f85-4f94afdadffe
productImage class java.lang.String http://ta-sj29.marketo.com/rs/717-ICG-368/images/item.png
productName class java.lang.String item
date class java.lang.String 2020-04-21 08:20:02
leadID class java.lang.String 2
productCTA class java.lang.String https://www.mdg.co.in/product/item2.html
productID class java.lang.String 059130d0-b9a5-4691-9f85-4f94afdadffe
productImage class java.lang.String http://ta-sj29.marketo.com/rs/717-ICG-368/images/item2.png
productName class java.lang.String item1
date class java.lang.String 2020-05-22 08:20:02
leadID class java.lang.String 3
productCTA class java.lang.String https://www.mdg.co.in/product/item3.html
productID class java.lang.String 059130d0-b9a5-4691-9f85-4f94afdadffe
productImage class java.lang.String http://ta-sj29.marketo.com/rs/717-ICG-368/images/item3.png
productName class java.lang.String item2
[{date=2020-03-20 08:20:02, leadID=1, productCTA=https://www.mdg.co.in/product/item.html, productID=059130d0-b9a5-4691-9f85-4f94afdadffe, productImage=http://ta-sj29.marketo.com/rs/717-ICG-368/images/item.png, productName=item}, {date=2020-04-21 08:20:02, leadID=2, productCTA=https://www.mdg.co.in/product/item2.html, productID=059130d0-b9a5-4691-9f85-4f94afdadffe, productImage=http://ta-sj29.marketo.com/rs/717-ICG-368/images/item2.png, productName=item1}, {date=2020-05-22 08:20:02, leadID=3, productCTA=https://www.mdg.co.in/product/item3.html, productID=059130d0-b9a5-4691-9f85-4f94afdadffe, productImage=http://ta-sj29.marketo.com/rs/717-ICG-368/images/item3.png, productName=item2}]
Hi Sanford,
I was wondering if you have gone through the debug code and please let me know the details.
This line:
#if( !$display.alt($pro_cList["productName"],"").isEmpty() )
Should be:
#if( !$display.alt($pro_c["productName"],"").isEmpty() )
Remember, when you're iterating over the items ($pro_c) in the list, you want to test the item, not the whole list.