Skip navigation
All Places > Products > Blog > 2019 > February
2019

In this edition of Marketo Master Class, Marketo Champion Julz James took some time to share her expertise on the topic of forms and gated content. Specifically, she explores the best scenarios to utilize forms, gated content best practices, and leveraging progressive profiling to get the most out of your Marketing efforts. Read on to discover how Juli uses forms in conjunction with gated content to seamlessly gather data without disrupting the customer experience.

 

1. What are the benefits of Marketo forms?

The benefit of using Marketo forms is pretty simple. The forms are easy to create, plug into campaigns, and ensure that data is being captured for any of your content-driven campaigns, whilst also allowing you to monitor real time content downloads and report out on what content is getting the most engagement.

 

They’re also great to use for event registration as you can tie the form to your event campaign, put it onto the event registration landing page and the monitor real time registrations. I’ve also recently been playing around with real time content delivery at events.

 

The beauty of Marketo forms is that you can add any CSS you want to it, as well as add some cool Javascript to make the forms look and behave in the way that you want to, without needing to get developers or IT involved. And then you can use them to scale your campaigns.

 

There are obvious examples of when you must use a form, such as capturing event registration. Tracking of all event registrations is imperative, whether online or offline. Having the registrations via Marketo forms means that you can send out confirmations, reminders and updates automatically using trigger campaigns, rather than having to download registration information from somewhere else and uploading to Marketo.

 

2. What situations warrant global vs. local forms?

I will always lean towards global forms as much as possible. Purely down to a scalability factor. A bit like CSS for websites, if you need to make a change to a form and you’re using global forms, then you only need to make that change in one place and then bulk approve the landing pages from design studio. If you had only local forms then you would have to go into each campaign and adjust each form.

 

 

An example would be when GDPR was introduced. I’ve heard various horror stories of people having to go into 600+ forms to add the GDPR rules for opt-in, rather than just going into 1 form and bulk approving 600 landing pages, which takes minutes vs. hours.

 

However, there is sometimes a need for local forms. I would suggest using local forms if your program requires specific data to be collected. For example, say you have an event where you are required to ask guests their dietary needs, or t-shirt size, or your field marketing manager wants to collect specific interests that won’t be relevant elsewhere. A local form would fulfill that need.I would also suggest a local form if you have to do a specific campaign in a different language. I’ve worked on landing pages in multiple languages but they’ve only been created once or twice, so then I would only create local forms as its highly unlikely they’ll get used again. If I find that I’m using a form more than a few times, I’ll add it to the Design studio and start using as a Global Form, although I try to keep the number of Global Forms down as well.

 

3. What type of content do you leave ungated? What content is important to gate?

I try my hardest to not leave content ungated, but rather to use the ‘Known Person’ option on the form to provide a simple ‘download now’ button instead of a form, or I like to use a Marketo Partner such as Uberflip that will track content downloads without the need for too many forms.

 

The whole point of gating content is to track who is engaging with the content you are providing and creating. Moreover, having gated content will help with tracking which content is providing the most conversions to analyze which content is the most effective. If you left all content ungated (as is the suggestion of some industry experts), then there is no way to track and convert potential new customers. It also depends on the value of the content. I would not gate an infographic for example, but I would most definitely gate a whitepaper or analyst report.

 

4. How do you synchronize progressive profiles built from forms/gated content with your marketing campaigns at large?

I like to use progressive profiling forms to build up records user profilesto further segment and personalize the types of campaigns that are being sent out. For example, if I’m using ‘Industry’ on a form it’s because I want to further segment down the industries into Strategic Business Units using an approved segmentation. Having data segmented means that emails can now be sent out using dynamic content based on segments.

 

This is especially useful for Nurture campaigns if you work with multiple languages. You can set up your segmentation based on the country information that has been populated from the progressive profile form and then use those segments to create dynamic content to send the same email in the preferred language of each record.

 

 

 

5. What are some of the most underutilized features on forms?

Prior to GDPR I would have said the most underutilized feature on forms were the visibility rules. Having the ability to only show certain fields when other fields on the form are completed is a great feature! If you’re not using visibility fields for anything on your forms, and especially for GDPR you should look into it.

 

 

You can also set up field sets to be shown dynamically based on visibility rules too:https://docs.marketo.com/display/public/DOCS/Add+a+FieldSet+to+a+Form

 

Another feature that really isn’t used enough and that Sanford Whiteman has recently authored a post about is the use of the ‘known person’ option in the Settings section of the Form editor. He talks about not just showing a button rather than the form, but also how to set up an Auto Submit for known users, which will help to provide an excellent customer experience for those users who are already in your database, whilst at the same time recording the ‘Form Fill’.

 

One last feature that I don’t see utilized very often but could be helpful is Input Masking, to ensure that values being put into certain fields are formatted in the correct way for data cleanliness:https://docs.marketo.com/display/public/DOCS/Apply+Input+Masking+to+a+Field+in+a+Form

 

 

6. What’s one tip about forms/gated content that you wish you learned sooner?

Over the last few months I have be working more with CSS and JavaScript on forms to manipulate them in a way to perform exactly as requested. For example, Sanford also wrote a post a while ago about adding JavaScript to forms:

 

And there are some great tips for form manipulation for embedded forms using JavaScript on the Developer Site too:http://developers.marketo.com/rest-api/assets/forms/examples/

I really wish I’d learn that you could do more than just create a form and play with the CSS a long time ago.

 

I’ve also recently learnt how to add 2 forms to one page with some JavaScript, and that was a technique that I wish I had a long time ago. Below are how it looks on the Landing Page, the HTML on the landing page and the custom

 

Screen Shot 2019-02-19 at 11.17.41 AM.png

7. Are you planning to try anything new with forms/gated content in 2019?

For 2019 I plan on working more with Velocity Script in conjunction with Form fills so that real-time content delivery can happen at events. For example, having an iPad with a form on showing content related to that event, and then the users can select which content they find interesting and have that delivered in real time to them via email. This will save the need for a lot of collateral being printed, but it will also help to grow the database organically.

 

I’m also hoping to spend more time with form CSS to improve the customer experience and look of forms across various platforms. I think CSS alongside Javascript and Velocity Script can make for some really interesting user experiences for known and unknown records looking for content. For example, forms that auto submit in the background for known users so they get direct access to the content without having to resubmit the same information numerous times would allow for a more frictionless customer experience. Essentially, if less clicks are required between a lead and the content they are likely to consume, it’s much easier to move along the funnel.

 

 

We hope you enjoyed reading about how Juli James is leveraging forms and gated content seamlessly gather data without disrupting customer experience. If you have any examples of how you've used these features to better engage with your customers, please let us know in the comments!

 

You can find more informative content in the brand new edition of our customer newsletter, the Fearless Forum.

Printing fallback content when a Lead field is blank is a basic Velocity task. You can do it in a few lines of clunky code... but that's a few lines too many!

 

Seeking a one-liner, you might reach for Velocity's built-in $display.alt. But that won't fill the bill in Marketo-land. You see, $display.alt($field, $fallback) outputs the fallback if the field is null. But null isn't the same as the empty String that Marketo uses for unfilled Lead fields.

 

Therefore, the code

 

Dear ${display.alt($lead.FirstName,"Friend")},

 

will only ever output

 

Dear Joe,

 

or

 

Dear ,

 

It will never fall back to

 

Dear Friend,

 

because Marketo ensures $lead.FirstName is always a String of some kind, never null.[1]

 

So without any other tools at your disposal, you're left with a typically wordy #if block:

 

Dear ##

#if( $lead.FirstName.isEmpty() )

Friend,##

#else

$lead.FirstName,##

#end

 

This will work fine, but as your scripts get cluttered with repeats of this same structure, you start to go a little crazy.[2]

 

The good news is there's a short Velocimacro you can include globally that greatly lightens the load. Once you set up the #displayIfFilled macro, you can reduce the logic to one easy-to-read line:

 

Dear #displayIfFilled($lead.FirstName, "Friend"),

 

Building #displayIfFilled

Here's the macro definition:

 

#macro ( displayIfFilled $checkValue $fallbackValue )
#if( !($checkValue.isEmpty()) && !($checkValue == $display.get("0")) )
$!checkValue##
#else
$!fallbackValue##
#end
#end

 

As you can see, #displayIfFilled takes 2 self-explanatory arguments: the field to check for filled-ness, and the fallback value.

 

#displayIfFilled is designed to treat null the same as the empty String. It thus covers a superset of the cases covered by $display.alt, so you may never be tempted by the latter function again.

 

Step further out: #displayIf

We can abstract the functionality of #displayIfFilled into a more general #displayIf:

 

#macro ( displayIf $truePredicate $trueValue $falseValue )
#if( $truePredicate )
$!trueValue##
#else
$!falseValue##
#end
#end

 

#displayIf takes 3 arguments: a Boolean, the value to output if the Boolean is true, and the output if the Boolean is false.

 

To emulate #displayIfFilled, pass an isEmpty() check as the first arg (the $truePredicate):

 

Dear #displayIf($lead.FirstName.isEmpty(), "Friend", $lead.FirstName),

 

Lots of tricks up your sleeve with #displayIf. Say you want to switch output based on a specific non-empty value

 

Your #displayIf($lead.trialType.equals("Other"), "VIP", ${lead.trialType}) trial is almost over!

 

or output based on a date/time property

 

Good #displayIf($calNow.get($calFields.AM_PM).equals($calFields.AM), "mornin'", "aft'noon")!

 

or anything that can be expressed as if-then-else!

 

Of course, #displayIf can be overused; past a certain point of complexity, you should be using #if-#else on separate lines. But where a one-liner doesn't hurt readability, I say use it. #displayIf is critical to my sanity (if I have any left) as an avid Velocity coder.

 

Stay functional

There's another detail that you'd eventually learn on your own, but I'll spoil it to save you time.

 

When passing macro arguments in parentheses, you can include any chain of function calls but not syntactical expressions. For example, though Boolean operators and expressions are valid in other parts of Velocity, you can't do:

 

#displayIf(!$lead.FirstName.isEmpty(), "${lead.FirstName}'s", "Your") special offer is ready!

 

That won't compile because of the !. Velocity's parser doesn't accept operators in that place (nor would it accept <, > or == operators there).

 

Instead, either chain with the equals() function:

 

#displayIf($lead.FirstName.isEmpty().equals(false), "${lead.FirstName}'s", "Your") special offer is ready!

 

or as some programming style guides suggest anyway don't rely on negated Booleans and instead put your true case first:

 

#displayIf($lead.FirstName.isEmpty(), "Your", "${lead.FirstName}'s") special offer is ready!

 

To be clear, this doesn't mean you can't use all manner of operators and expressions to construct Boolean values, you just can't use them directly inside the parentheses when calling a macro. This will work fine:

 

#set( $hasCompany = !$lead.Company.isEmpty() && !$lead.Company.equals("N/A") )

Is #displayIf($hasCompany, $lead.Company, "your family") in the mood for pizza?

 

Disrupts the dream of a one-line solution, though.

 

What's with $display.get("0")?

Ah, yes. I don't want to overwhelm you earlier with the details of null checking in Velocity.

 

$display.get("0") (up above in the first #displayIfFilled macro) gets the value of a reference that is guaranteed to not exist, i.e. guaranteed to be null, in any Velocity context.

 

Why is it guaranteed to not exist? Because neither Java nor Velocity variable names are allowed to begin with a number.

 

Why not compare to the literal null? Because and this reality sneaks up in other important places in Velocity there is no four-letter keyword null! The null-ability of injected data is honored, even favored, in Velocity, like by $display.alt as noted above. But it doesn't have a keyword to create new null values easily.

 

So you have to find a roundabout way of getting a reference to a null value. Elsewhere on the net, people say "just use a variable you didn't #set anywhere else, like $abcdefg, as that will naturally be null." The flaw in this reasoning is nothing actually stops someone else (either a future coder or a current collaborator) from using $abcdefg for something else. So I prefer to use a reference that cannot exist even by coincidence.

 

 


 

 

Notes

[1] In the Marketo Lead/Person world, you aren't gonna run into literal null values, but rather empty strings. This is true despite non-filled fields being represented as [null] or NULL in parts of the Marketo UI. You can and will encounter null with Custom Objects, though. That's the stuff of another post.

 

[2] Yes, you could smush the VTL into one line. But if you think Dear #if($lead.FirstName.isEmpty())Friend#else${lead.FirstName}#end, is sufficiently readable, you're made of stronger stuff than me.

Filter Blog

By date: By tag: