Today I saw a post in one of the SDN forums asking how one could go about building a page in Sitecore that can render a Web Forms for Marketers (WFFM) form based on an ID passed via the query string.
I built the following WFFM FormRenderer as a “proof of concept” to accomplish this — this solution assumes the ID we are passing is the ID of the form, and not some other ID (or guid):
using System; using System.Web; using Sitecore.Data.Items; using Sitecore.Diagnostics; using Sitecore.Form.Core.Configuration; using Sitecore.Form.Core.Renderings; namespace Sitecore.Sandbox.Form.Core.Renderings { public class DetectIDFormRenderer : FormRender { protected override void OnInit(System.EventArgs e) { string detectedFormId = GetDetectedFormId(); if (IsValidFormId(detectedFormId)) { FormID = detectedFormId; } base.OnInit(e); } private static string GetDetectedFormId() { return HttpContext.Current.Request["formId"]; } private static bool IsValidFormId(string id) { return !string.IsNullOrWhiteSpace(id) && IsID(id) && IsFormId(id); } private static bool IsID(string id) { Sitecore.Data.ID sitecoreID; return Sitecore.Data.ID.TryParse(id, out sitecoreID); } private static bool IsFormId(string id) { Item item = StaticSettings.ContextDatabase.GetItem(id); return item != null && item.TemplateID == IDs.FormTemplateID; } } }
The FormRenderer above grabs the specified form’s ID via a query string parameter, ascertains whether it’s truly an ID, and determines whether it is an ID of a WFFM Form in Sitecore — these are done via the IsID and IsFormId methods.
If the supplied form ID is valid, we save it to the FormID property defined in the base FormerRender class. Otherwise, we flow through to the “out of the box” logic.
Now it’s time to register the above class in Sitecore.
I duplicated the “out of the box” Form Webcontrol under /sitecore/layout/Renderings/Modules/Web Forms for Marketers, renamed the item to something appropriate, and updated the code-defining fields to point to our new FormRender above:
I decided to reuse an existing page item with a WFFM form — I didn’t want to step through ‘Insert Form’ wizard so that I could save time — and swapped out the “out of the box” Form Webcontrol with the new one we created above:
I ensured we had a default form set just in case of query string manipulation, or in the event the form cannot be found by the given ID:
I published everything, and navigated to my form page:
I then specified the empty guid:
I manipulated the query string again, but this time passing a valid form ID:
I then changed the form ID again but with another valid form ID:
If you have any suggestions around making this better, or ideas for a different solution, please drop a comment.
This was a really useful post, thanks Mike. I needed to do a similar thing as I wanted to add a wrapping by overriding the DoRender() method. However I also had to take a copy of the GetDialogUrl pipeline from: Sitecore.Form.Core.Pipeline.InsertRenderings and modify it to accept my Form Interpreter ID as (in WFFM 2.4 at least) it checks the ID of the Form Interpreter and rejects it if it isn’t the standard one. This means content editors do not get to see the InsertFormWizard popup to create new forms when adding the form rendering (using page editor) to the page. Adding this copy of the pipeline for my Form Interpreter ID fixed this.