Multisite WFFM Form Markup using MVC Areas

If you are using the MVC version of the WFFM module then you probably know that by default the templates for the fields are located under /Views/Form/EditorTemplates folder. If you have a multisite implementation then this leads to an issue if you need to render different markup for different sites. Generally speaking, my recommendation has always been to try style around the default WFFM markup rather than bending it to your will only to be struck down later when upgrading, but we should try to follow this same advice for most of Sitecore whenever possible anyway.

But sometimes you really really need something different per site.

With the release of Sitecore 8.1 we have had the added benefit of being able to use MVC Areas. We can take advantage of this feature to allow different markup for forms per site.

WFFM per Site

It’s already possible to specify a different forms folder per site by setting the formsRoot attribute on your site node:

<site name="website" set:formsRoot="{F1F7AAB6-C8CE-422F-A214-F610C109FA63}" /> 

You can read more in the WFFM docs. This only deals with the forms folder container in the tree though but allows you to group your forms per site (selection and creation).

In order to provide different markup per site we can define the form and field templates using MVC Areas. There are a number of strategies for setting the area but we use an approach which was blogged by Kevin Brechbühl, that is, we set an attribute on the site node:

<site name="website" set:mvcArea="mysite" /> 

(By now, you should be able to tell I like using additional properties on the site node!)

Now copy the entire /Views/Form folder into the Views folder of your area, including the web.config as well.
Edit.
Profit.

WFFM Form Field Templates

WFFM Form Field Templates with MVC Areas

If you create any custom fields then remember to create the cshtml in all locations, the default WFFM folder and the Areas folder.

Overriding Default Form and Fields Markup

Unfortunately, there is no fallback so you have to provide implementations of all fields templates in the areas folder, even if they are unchanged. It won’t fallback to the default Views folder for Editor Templates, they must all reside in the same area folder.

But what if you want to update the markup of the default fields for all sites? You have three options:

  1. Update the default files located in /Views/Form/EditorTemplates. You potentially have the issue that if these file have changed during an upgrade. I won’t judge, sometimes you just need to get something to work. I’ve done it myself. You’ve done it too, even if you won’t admit it out loud. 😇
  2. Create an area for every site you have and add/duplicate the Forms folder. Or do 1 above and only create a new area folder for those few sites that need the different mark-up. Still not judging remember. 😇
  3. If you have a multi multi multi multi multi site implementation and the markup of the form fields are the same for all but a few sites then duplicating the fields into areas might not be ideal. You could probably do something using Symbolic Links but it’s also possible to add additional custom locations to the Razor View Engine.
public virtual void Process(PipelineArgs args)
{
    var rve = (RazorViewEngine)ViewEngines.Engines
        .FirstOrDefault(e => e.GetType() == typeof(RazorViewEngine));

    string[] viewLocations = {
        "~/Areas/Common/Views/{1}/{0}.cshtml"
    };

    if (rve == null)
        throw new NullReferenceException("Razor View Engine is null");
    
    rve.ViewLocationFormats = viewLocations.Union(rve.ViewLocationFormats).ToArray();
    rve.PartialViewLocationFormats = viewLocations.Union(rve.PartialViewLocationFormats).ToArray();
}
<pipelines>
  <initialize>
    <processor type="MyProject.Custom.Pipelines.RegisterCustomRazorEngine, MyProject.Custom" />
  </initialize>
</pipelines>

We add an additional Common Area location for the View Engine to search engine to search within for our markup. This keeps the default WFFM code completely untouched. (See the Visual Studio folder structure in the earlier image)

This code is not highly tested, although we use similar code elsewhere in the site, we just go with option 1 and 2 above. I didn’t judge you, now don’t judge me… 👼

Further Reading

During my search writing this article I found this post by Charlie Turano about Customizing WFFM in Sitecore 8 which essentially does the same thing for earlier versions of Sitecore 8. They went a different route and used an MVC Areas module by Brainjocks (since there was no OOTB Area support in Sitecore at the time remember). I highly recommend you read both of these articles though. Since we are still using the default MVC Form rendering and have not duplicated it, we don’t have the same issues mentioned in that article about the InsertFormWizard. Funnily enough, our project also uses Foundation but we just styled around the issue in early 8.x releases, and WFFM 8.0 Update-6 introduced the Bootstrap framework, where we just disabled the Bootstrap CSS and styled around it again
😊

Let me know if you have any thoughts or have solved this in a different way!

Area 51

Links:

  1. Customizing WFFM in Sitecore 8
  2. Sitecore Support for MVC Areas
  3. Symbolic Links
  4. New in Sitecore 8.1: MVC Areas
  5. Sitecore – MVC areas
  6. MVC Areas in Sitecore 8.1: A Step-By-Step Guide
  7. Change form items storage location
  8. ASP.NET MVC – Add custom locations to the View Engine default search patterns
  9. What are Display and Editor Templates? – ASP.NET MVC Demystified

Leave a comment