Velocity does something magical when you just output a Lead field (without any other code at all). The magic: it truly outputs the value as stored in Marketo. A {{lead.token}} doesn’t do that by default.
Community user AB wondered why a Textarea containing an HTML table was revealing raw HTML (as text) in emails, as opposed to rendering the table.
That is, if a field looks like this in the UI:
Here’s what you see if you include {{lead.The Field With HTML}} in an email:
While you might have expected to see:
The reason you see the HTML-as-text is simple: Marketo HTML-encodes token values by default.
There’s nothing wrong, and a lot right, with this being the default behavior. It’s the same way that browsers deal with HTML-like text that’s not specifically inserted as HTML. For example, open a browser tab, go to the Dev Tools Console, and run
document.body.insertAdjacentText("afterBegin","<table><tr><td>Stuff</td><tr></table>")
and you’ll see the code for a table, not a table!
In AB’s case the encoded value is:
<table><tr><td>Access Code</td><td>Remaining Uses</td><td>Start Date</td><td>End Date</td></tr><tr><td>hh7zh-lgyal</td><td>2.0</td><td>2018-12-31 08:00:00</td><td>2019-12-30 08:00:00</td><td></table>
Basic stuff, the <
and >
are encoded so the web browser/mail client won’t look for any deeper meaning in the text.
The old answer
The ready answer you might see for this is “Turn off HTML Encode Tokens in Field Management.”
I’ve given this answer myself. It works as a just-in-time fix. But I don’t feel it’s the right answer anymore, for multiple reasons:
- you (the email author) may not have permission to make this change
- if a field is used for multiple purposes, it may not be globally correct to leave the value unencoded
- encoding is a secure default
The new answer
Using Velocity gives you local (per-email, even per-lead) control over whether the value is encoded.
To output a field without encoding, just create a {{my.token}} and drag that field to the canvas:
If you decide you do want to encode, Velocity has a method for that, EscapeTool.html
:
${esc.html($lead.TheFieldWithHTML)}
Now you’re in control of whether the output differs from the stored value.
Another related case
If you’re in the unlikely-but-not-unheard-of situation where an integration is plopping HTML into a field where you just want text, then it’s not just encoded vs. unencoded. You want the HTML tags outta there completely.
For that you use DisplayTool.stripTags
:
${display.stripTags($lead.TheFieldWithHTML)}
If you want to keep (whitelist) specific tags, pass all those tags as the 2nd+ arguments. With this VTL…
${display.stripTags( $lead.TheFieldWithHTML, "td", "tr")}
… this original value…
<table><tr><td>Access Code</td><td>Remaining Uses</td><td>Start Date</td><td>End Date</td></tr><tr><td>hh7zh-lgyal</td><td>2.0</td><td>2018-12-31 08:00:00</td><td>2019-12-30 08:00:00</td><td></table>
… gets output like so:
<tr><td>Access Code</td><td>Remaining Uses</td><td>Start Date</td><td>End Date</td></tr><tr><td>hh7zh-lgyal</td><td>2.0</td><td>2018-12-31 08:00:00</td><td>2019-12-30 08:00:00</td><td>
Could be handy if you have a system that’s wrapping HTML in extra containers, disrupting your layout.
Note stripTags
acts like textContent
in a browser: all the matched opening and closing tags are removed, they’re not replaced by anything. So you might get unpretty output: <div>Sandy</div>Whiteman
becomes SandyWhiteman
(note the lack of space). Whether this works for your case depends on what’s coming in.