Choosing Landing Page will give you a nice dropdown of all your approved Marketo LPs.

Choosing External URL and entering the full URL of a Marketo LP seems to work, too — but it's a bad move. Form Editor won't tell you why, but I will.☺

The problem

If you choose Landing Page or Stay on Page, Marketo uses a special read-your-write feature to ensure Pre-Fill on the next pageview.[1]

If you choose External URL, Marketo looks up the URL in your known LPs but it doesn't look in your Redirect Rules. If the URL is not seen as a core LP URL, even if it does lead to a Marketo LP in reality, then the read-your-write Pre-Fill cache is not enabled.

What is “read-your-write” and why should I care?

“Read-your-write” or RYW is a desirable, but not always supported, feature of distributed systems. (A distributed system is any system that processes data at multiple tiers, like we all know Marketo does.)

RYW, in a nutshell, means:

If a user thinks they've made a change to the back end, then show them the new data as if it's been fully saved, regardless of whether system(s) may be still filtering and processing — or even discarding! — the data in the background.

It doesn't mean anybody else sees uncommitted data (there are some cases in which it won't be saved, so you don't want to propagate bad info more widely than necessary).

It means that for a less confusing user experience, you let a user see their own requested update immediately, instead of forcing them to see older saved data for a few seconds/minutes (even though showing saved data would technically be more accurate end-to-end).

Marketo implements read-your-write via the special query parameter aliId. It's a numeric identifier for a set of submitted form values, and it's usable regardless of whether the values are actually saved. When a page has an aliIdin the URL, it's capable of (for the most potent example) filling a second form using the data from a first form, even if it was submitted mere milliseconds before.

Back to Form Editor

When you choose External URL in Form Editor, Marketo tries to append the aliId intelligently, but it can't know about your redirects (especially 3rd-party redirects) or anything that might disguise the Marketo-ness of the destination URL. As a result, the next LP someone views may show their session's old data (maybe including someone else's email) or no data at all (the session still being effectively anonymous). You don't want that! So choose Landing Page if it's indeed a Marketo LP.

Other complications

When you use the Forms JS API onSuccessmethod to choose a Thank You URL dynamically (a very powerful option) set the form to Stay on Page in Form Editor, as this will ensure the aliIdis appended.

Then clip out and append the original query string, which will include the aliId, to the dynamic URL.

If you're using a fuller-featured URI parser/builder already, like uri.js, use that instead of the Link/Location method (though the location.search breakdown works perfectly, since it's a key browser function).

Just don't write your own parser… I don't want to have to holler at you again!

NOTES

[1] When you use Stay on Page the aliId is attached even if you're using the form embed and the page is a non-Marketo page. It's not fully honored in this case (since Pre-Fill isn't supported with the embed) but it's better to have it there than not.

Accelerate your Marketo learning at the Marketing Nation Summit 2018! Join us at University Day on April 29, 2018, where you can take your Marketo skills to the next level and build expertise will focused instruction, practical demonstrations, and inspiring presentations by our Marketo experts.

Little-publicized, to the point that even Support might not be in the loop: the Visibility RuleContainsoperatordoesallow multiple values.

TheContainsvalue is interpreted as a full-fledged regular expression, so use the pipe character|to separate sub-values:

In fact, because of this unexpected/undocumented power, you must anchor an expression to avoid surprises:

^(TX|FL|PA)$

Otherwise, it's doing a partial match of the full value againsteachof your pipe-delimited alternatives. This might not be a problem on your forms right now, but if it becomes a problem, you wouldn't know about it immediately.

For example, if you were using uppercase state names, then

ContainsKANSAS|IDAHO

would match bothARKANSASandKANSAS, and you should use

Contains^(KANSAS|IDAHO)$

instead.

You can also of course do more fancy matches with regexes if you want. AndNot Containsis also a regex!

Simple notation should be your default. Formal notation should only be used when there's no alternative. As the Velocity docs say:

In almost all cases you will use the shorthand notation for references, but in some cases the formal notation is required for correct processing.

I'd go further: when used unnecessarily, formal notation can make your code confusing and fragile. Unfortunately, Marketo's script editor doesn't encourage best practices, because when you drag a field from the field tree to the editor canvas, it's automatically wrapped in ${}:

My recommendation: remove the curly braces right away, and only restore them if it proves necessary during development.

What can go wrong?

A recent Community post shows how confusing things can get when you use formal notation unnecessarily (note how the poster titled it "... tokens behave unexpectedly" when it's actually established behavior, if not well-circulated).

The catch: a reference enclosed in ${formal.notation}cannot be chained with a method/property outside the curly braces.

OK, that probably didn't make sense unless you're fluent in OO-speak! Let's look at some examples.

This does work with simple notation:

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

It doesn't work if you only enclose part of the expression in formal notation:

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

Sure, it would work if you happened to enclose the entire expression in curlies —

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

— but you should just use simple notation instead, because it's harder to mess up during refactoring.

Don't believe me? (You probably do, or I'd like to hear who's more authoritative about Velocity.☺) Consider what happens when you move from a not-best-practice, but syntax-error-free, comparison using double-equals ==:

#(if ${lead.numberOfProducts} == 0 )

to a more forward-looking equals():

#if( ${lead.numberOfProducts}.equals(0) )

Suddenly, your Velocity token stops working because you can't have a . after a }. It may be clear, to you as a human, what you meant, but VTL doesn't allow it. If you'd used simple notation from the start you wouldn't have to make such adjustments.

When do you need to go formal?

Formal notation should only be consideredinside strings or output, and only used when the separation between variables and static text would otherwise be unclear.

If you're in a line of code starting with #if or #set chances are very slim that you should be using formal notation.

You've seenbeforethat the Forms 2.0 input mask plugin can be tweaked to do some more elegant stuff.

Here are a few more things you might want to do. I only recommend masks for things that have an explicit standard (like phone numbers, credit cards, etc.). But if you're going to use them for more than that, use them wisely!

The code is bundled at the bottom of the post.

SUPPRESS THE UNDERSCORE AS THE PLACEHOLDER

By default, the mask shows a _ character in every empty position up to the max length.

This can look ugly, especially if there's already a hint in the field telling people it's limited toNcharacters.

You can remove the placeholder character entirely or replace it with something else (though I'm not sure anything isbetterthan underscore or blank in this case, maybe a cursor block like ░ if you want to be retro-cool?).

ACCEPT ANY LATIN-1 LETTER, NOT JUSTA-ZANDa-z

When you select theashortcut in the Form Editor…

… you're actually blocking all but the slimmest subset of alphanumeric characters.Even the e-with-acute-accent inGrégoireis blocked!That's not good when words contain theseslightlyout-of-the-American-ordinary characters.

It works this way because, under the hood, input masks use the regex character class [A-Za-z] to implementa. And that's ASCII unaccented letters only.

The better move is to use a class like [A-Za-z\u00C0-\u024F]which includes Latin accented letters, i.e. those from Romance languages. (You'll still be blocking people who spell their names using other glyphs, but that's another matter.)

Better still, if you're in the world of names, allow hyphens, apostrophes, periods, and spaces: [A-Za-z\u00C0-\u024F'. -].

ALLOW SPACES, NOT JUST CHARACTERS

When you set a mask to**********, even if you don't want non-ASCII, non-accented characters, do youreallymean that spaces aren't allowed? Sometimes yes, sometimes no.

In the case of ISBN-10s, for example, no spaces are allowed per the international standard, and you might want to block spaces in the Phone field for standardization.

But in the case of First or Last Name, Company, or tons of other cases, you certainly don't want to block spaces.

MAKE IT HAPPEN

All of the above functions can be enabled with the helper JS below.

First, in Form Editor,give each field you want to re-mask an initial mask (any mask pattern will do). (If it isn't masked to begin with, we can't tweak the mask setup.)

Then add your custom patterns to the inputMasks array as below: the name property is the Marketo form field name and the rest is explained in the comments.

Be sure you sign up for as many of these 18 (2X more than at Summit 2017!!!) fabulous Marketo Technical & Foundational Techniques track sessions from our very own amazing Marketo Champions and Champion Alumni as you can:

Analytics That Matter: Reports For Every Stage of the Funnel -- Digital Pi

The number one thing we heard from you in your feedback from Summit 2017 was that you wanted more workshops! As you can see, we are offering eight of the above content sessions as workshops where you have the opportunity for a more intimate and interactive session with our most experienced speakers.