Web forms for marketers (WFFM) to anything

Need to post your WFFM data to an external service? Read on.

So lets start by describing the problem we are trying to solve. WFFM is a great way for content editors to go wild and create forms all over the website. As developers we are often asked to integrate web forms with various external services, one example I worked on recently was posting the submitted form data to Salesforce.

Where we post the data to isn't really the problem, with most APIs this is a few lines of code. The difficulty lies in mapping the WFFM fields to our external API / service, bearing in mind that properties could be added or modified at the service at any time.

We could rely on our content editors to name their WFFM fields based on the field names at the service. This would provide a 1-to-1 mapping between the two but this is a bad idea for many reasons:

  • We should not restrict ourselves to using property/field names of the external service's data store for our form labels.
  • it requires our content editors to have knowledge of the service's internal data structure.

WFFM To Anything allows content editors to pick a mapping for each field.

Example

All you need to do to use WFFM To Anything is:

1) Download and install the Sitecore package here
2) Reference the WFFMToAnything.Core assembly from your web project.
3) Write some code which implements the IWFFMToAnythingGet interface - this code retrieves possible field/property values from your service.
4) Write some code which implements the IWFFMToAnythingPost interface - this code will be executed after a user submits the form - you are given a data object containing field mappings and user inputs and need to post it to your external service.
5) Let WFFM To Anything know where the code you've just written lives.

Thats it. You can even create multiple implementations for different services.

Implementing IWFFMToAnythingGet

Below is an example how to implement the Get interface. You need to fill the ServiceFieldData object with Display Name / Identifier key value pairs so that WFFM To Anything knows which fields are available from your service.

public class GetFromDummyAPI : IWFFMToAnythingGet
{
    public ServiceFieldData GetFieldData()
    {
        // Connect to your API / Service
        MyAPI api = new MyAPI();

        // Get a list of fields (key = displayname, value = identifier)
        return new ServiceFieldData() { FieldData = MyUserFieldDataAssembler.Assemble(api.GetUserFields()) };
    }
}

Our dummy assembler simply takes data from our service / API and converts it into the ServiceFieldData type. This type has one member, FieldData which is a Dictionary. (Display Name / Identifier).

Implementing IWFFMToAnythingPost

Below is an example of implementing the Post action. Your implementation of the SaveToDestination method will be excuted when the user submits a form.

public class SaveToDummyAPI : IWFFMToAnythingPost
{
    public void SaveToDestination(IEnumerable<FormFieldData> data)
    {
        // Post form data to my API.
        MyAPI api = new MyAPI();

        api.AddUser(AssembleUserFromFormData(data));
    }

    private User AssembleUserFromFormData(IEnumerable<FormFieldData> data)
    {
        User user = new User();

        user.Title = data.FirstOrDefault(i => i.DestinationFieldIdentifier == "Title").InputValue;

        return user;
    }
}

As you can see you will be presented with a data object containing user input, your service field identifiers and the WFFM fields they are mapped to. It should be trivial to post this data to your service.

Tell WFFM To Anything where your code lives

Add a few entries to your AppSettings which will be shared between all forms which have WFFM To Anything enabled:

    <add key="WFFMToAnything.Get.AssemblyName" value="WFFMToAnything.ImplementationTest"/>
    <add key="WFFMToAnything.Get.ClassName" value="WFFMToAnything.ImplementationTest.GetFromDummyAPI"/>
    <add key="WFFMToAnything.Post.AssemblyName" value="WFFMToAnything.ImplementationTest"/>
    <add key="WFFMToAnything.Post.ClassName" value="WFFMToAnything.ImplementationTest.SaveToDummyAPI"/>

If you'd like a different implementation of Get, or Post per form you can override these values on the form:

Example

That's it! You're ready to go!

Using WFFM To Anything

Using WFFM To Anything is really easy. If you content editor wants to build a form with a Single-Line Text field they should select the Single-Line Text To Anything field instead. (You can rename these fields to Single-Line Text To Salesforce for example. They then simply select from the dropdown the field the data should be posted to. Your code will take care of the rest.

After completing the form they must add the WFFM To Anything save action.

Advanced usage

I'll cover some extra things you can do and configure in my next blog post.

Dave Leigh

Web, and long time Sitecore developer based in Bristol, UK, working at Valtech - valtech.co.uk - @valtech.
I occasionally do other things too.