WFFM is a great tool. Don't get me wrong. It really is. 

It's just that sometimes it drives me nuts.

The other day, I set out to populate a contact us form, in a multilingual site, on a 8.1 update 2 Sitecore, with its relevant WFFM module installed. I set the form up in English first, added the stock "Send message" action, jotted down a simple email message with the submission data, and tested it. All was well.

Then I started tweaking it. First of all, the form had a dropdown, that did various things on change (via custom javascript of course), so I had to have different display texts and values. No problem there, I just went into Sitecore and did what had to be done in the form editor. But that broke the email message, because now, instead of the nice display text, I got the Sitecore ID of the selected option. Not good.

So I set out and used this amazing solution, ILSpy-ed the "send message" save action and rolled out my own. No biggie, in a matter of an hour I was up and running, with my custom javascript onchange event handlers on the WFFM droplist, and my custom made email sending save action with properly "shoehorned" values. I need to stress out here, that part of the solution is accessing the submitted values (the result set) by name, where name is the Item name of the WFFM fields of the form. Here comes the fun stuff:

Hidden Item Renaming

Then I went on to add the form in the other languages of the site. I had the translations handy, so it was a simple matter of data entry. Right? WRONG! After publishing, much to my horror, my form stopped functioning. I got the dreaded "your data may not have been saved" warning message I so well know and loathe.

So I went into the log, and lo and behold, a null reference exception on a line that accessed a result by name. Wondering what the issue may be, since I had already tested the thing before, I went into Sitecore to check the Item name - perhaps a capitalization issue. Imagine my surprise when I realized that Sitecore had changed the form field item names to the translated values of their titles. So the action could not locate the form field, and it all broke down in tears. Of course I changed the names back, but why would Sitecore rename the items in the first place? I only wanted a translation, not an item rename!

No Multilingual Email Messages

Then I went on to add a html template for the email message sent, with some images, and some fancy text apart from the submission data. I copy pasted the carefully crafted html, that had proper full url's for the images and tried it. All was ok. then I went on to change the language and add its translation, but NO! the Save Actions field, where the entire HTML is stored as html-encoded value of a XML fragment, is in fact a shared field! So no translations for you, mail message! 

Granted, more often than not, that's what you want. But when it comes to emails, which are client-facing things, Sitecore should have provisioned some kind of multilingual support. I found a post saying "just simply unshare the field". THAT'S A HACK IF I EVER SAW ONE! Of course I went on and unshared the field. It's working, but with a HUGE caveat. When you create a new "form" item, the standard values have a specific xml string for the "Save actions" field. You guessed it, when creating a new language version for the form, this field is now empty, thus breaking the sitecore client. My workaround is EVEN HACKIER, as I first switch to raw values, copy the xml from the first language, then create the version in the other language (with the "raw values" on, sitecore doesn't break) then paste the value in the field, save and switch back to normal display. Talk about additional administrative burden!

Eating away the server url from links and image src

Having done that, I went on to check the email sent and OH NO! All url's had their server part stripped! Apparently, that's something the DHTML Editor does. But then, the ProcessMessage pipeline (the one that parses the email, replaces tokens and sends the mail) does not restore them back, if they are not Sitecore links! 

So all links had to be converted to sitecore links. Fair enough, but with a lot of teeth clenching.

No images can be added via design mode

Fair enough, only Sitecore links. But what about images? The DHTML editor for the email message does not have a "add image" button! Cheap hack: add it via html, then right click on it and open the image properties. You can then go on and replace your dummy (or not so dummy) image with one from the Media Library. The src is now a propersitecore link, so it should be picked up by Sitecore and replaced with a fully qualified url with the servar part in. Only to find out that...

Sitecore links in Image Src attributes are not expanded

Because WFFM wants to throw yet another curveball. Apparently, the AddHostToMediaItem method only expands media item links that are in anchors (i.e. "<a href>"  stuff, not "<img src>" stuff). I had to roll out an additional custom pipeline processor for this (mostly ripped from the stock sitecore one though):

    public class ProcessMessage
    {
        private readonly string shortSrcMediaReplacer;

        public IItemRepository ItemRepository { get; set; }

        public IFieldProvider FieldProvider { get; set; }

        public ProcessMessage() : this(DependenciesManager.WebUtil) { }

        public ProcessMessage(IWebUtil webUtil)
        {
            Sitecore.Diagnostics.Assert.IsNotNull(webUtil, "webUtil");
            this.shortSrcMediaReplacer = string.Join(string.Empty, new string[]
			{
				"src=\"",
				webUtil.GetServerUrl(),
				"/-/"
			});
        }

        public void AddHostToMediaItem(ProcessMessageArgs args)
        {
            args.Mail.Replace("src=\"-/", this.shortSrcMediaReplacer);
            args.Mail.Replace("src=\"/-/", this.shortSrcMediaReplacer);
        }
    }

And then add it in a config patch:

<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
     <pipelines>
      <processMessage>
        <processor patch:after="processor[@method='AddHostToMediaItem']" 
                type="MyAssembly.Pipelines.Forms.ProcessMessage, MyAssembly" 
                method="AddHostToMediaItem" />
      </processMessage>
    </pipelines>
  </sitecore>
</configuration>


Finally, I had the form and the action the way I wanted it!

WFFM is fun to work with, but darned if it isn't quirky as can be!