It all starts with a series of problems – I want a Sitecore instance in MVC, I want to use Web Forms For Marketers (WFFM) with the MVC context, and I want my content authoring experience through the page editor to be straight forward.
Well, thanks to this blog post from Chris van de Steeg, my first two wants are fulfilled. In fact, the use of this can go beyond just WFFM to your existing control. Your controls can continue on in the MVC world.
In doing this with WFFM adding the control from the editor Insert Form option no longer is working. Chris details why this behavior happens in his blog.
“Wffm scans the current layout for <sc:placeholder /> tags, and let’s the user choose where to place the new marketing form. In razor, obviously, we don’t use the <sc:placeholder /> and unfortunately, the module does not let itself fool by adding one in comment.”
Chris then details the workaround by adding the form rendering to the presentation details, assigning to a place holder, and then editing the properties to select the appropriate form for the item.
There are just times we just don’t want the content authors to change presentation details. So selfishly back to what I want – a page editor experience suitable to provide the same experience without diving into the presentation details from the page editor. So below is a similar example of what I just wrapped up this past week for a customer.
First things first, on my standard values for my page template both my view with the placeholder for forms and the forms rendering assigned to my placeholder with no form selected.
Then I created my page and went off to the page editor to select the form I wanted for the rendering through the properties of the rendering component and this is what I got….
…nothing. With no initial form the rendering wasn’t putting out anything. So time to grab my favorite decompiler and walk through the code. This is what I found in the FormRender class…
if(this.form == null && this.Controls.Count == 0) { output.Write(this.RenderForm().ToString()); }
Well, with no form ID and no associated item and thus no form added to the controls, I am at the mercy of the output of RenderForm().ToString() which ironically returns a concatenation resulting in string.Empty.
So, looks like I need to extend the FormRender, create a new form rendering, and replace the original form rendering on my template with the new one. So I needed a default identifier when no form was available. I whipped up a quick image and made my DoRender method do something like this…
if (Sitecore.Context.Site.DisplayMode == DisplayMode.Edit) { output.Write("<div style=\"min-height:160px;\">"); output.Write("<img src='~/media/NoFormChosen' alt='No Form Chosen for Form Rendering' />"); output.Write("</div>"); } else { base.DoRender(output); }
Be careful on that override for the OnInit. The SitecoreSimpleForm has the property of FormItem which has a protected internal setter. You’ll need to keep that in consideration when creating the form and adding it to the controls collection.
With the necessary elements in place, all that is left is to create the properties button in the Custom Experience Buttons. Refer to Chris Castle’s post on some of the basic pieces of performing this (http://www.sitecore.net/Community/Technical-Blogs/Maximizing-Usability/Posts/2012/09/Using-Custom-Experience-Buttons.aspx). I derived mine from sitecore/content/Applications/WebEdit/Default Rendering Buttons/Properties and made some minor tweaks. I then associated the new button with my new form rendering and got what I wanted.
Now the content editors can set their forms using the page editor and they don’t have to work through the presentation details.
Great stuff here Mark. However, you may want to adjust your DoRender method slightly. They way you have it right now, it will render the “No form chosen” every time you are in the page editor even if you have a form id set. I did this, and it worked like a champ:
if (Sitecore.Context.Site.DisplayMode == DisplayMode.Edit)
{
string str = base.RenderForm().ToString();
if (!str.IsNullOrEmpty())
{
output.Write(str);
}
else
{
output.Write(“”);
output.Write(“No Form Chosen”);
output.Write(“”);
}
}
else
{
base.DoRender(output);
}
Nice Martin, I’ll have to take a look. What I put in for the default identifier was just a quick example for the blog. Thanks for sharing your approach!
Hi Mark
Can you please advice if i can go ahead and integrate WFFM with my MVC solution? what are the other issues you faced after integrating WFFM and what are the limitations it has??
Thanks
Onkar,
Absolutely you can integrate WFFM with MVC. That is the premise of this blog and Chris van de Steeg’s blog post referenced within. As far limitations and issues, nothing that was really MVC related. Adding WFFM forms to placeholders based on the two blog posts here should get you on your way.