Sitecore for Developers
EXM 3.1.1 installation
Getting this version (for Sitecore 8.0 update 4) of the Email Experience Manager to work takes a few more steps than are in the provided documentation. These steps can be found throughout the internet but I thought I would collect them here.
Subscription Form type is unavailable
EXM comes with a sublayout called the Subscription Form. This is an out-of-the-box control that will enter the user into a newsletter subscription engagement plan with a two step sign up process. Unfortunately the type for the view (Subscription Form.ascx) is not available in the EXM assemblies. The code-behind file is provided, but it has errors in it and will not compile.To fix this we just need to fix the cs file (Subscription Form.ascx.cs) or provide this type elsewhere. The solution for this can be found at https://community.sitecore.net/developers/f/10/t/1923#pi214filter=all&pi214scroll=falseChange this:[code highlight="4"]protected override void OnInit(EventArgs e){...this.recipientRepository = EcmFactory.GetDefaultFactory().Bl.RecipientRepository;...}[/code]to this:[code highlight="4"]protected override void OnInit(EventArgs e){...this.recipientRepository = RecipientRepository.GetDefaultInstance();...}[/code]And fully qualify the type of the Tracker.Current.Contact.ContactId:[code language="csharp" highlight="7"]protected virtual ID ContactId{get{if (!Email.Visible || string.IsNullOrEmpty(Email.Text)){return new ID(Sitecore.Analytics.Tracker.Current.Contact.ContactId);}...}}[/code]You may also need to add a reference to Sitecore.Analytics.Model
Rendering webforms controls in an MVC site
This problem is not specific to EXM, but if you're site uses MVC it is required to get the Subscription Form into a page. This solution can be found at http://www.chrisvandesteeg.nl/2014/02/11/usercontrol-renderings-in-a-sitecore-mvc-website-wffm-for-mvc/Add the UserControlRenderer and GetUserControlRenderer classes to your solution, and patch the mvc.getRenderer pipeline with mvc.usercontrolrenderer.config and you're good to go.The source can be found at https://github.com/efocus-nl/sitecore-mvc-usercontrolrenderer
Contact locking in MongoDB
Our developer machines will typically have multiple sites running on the same instance of MongoDB. Production environments frequently have multiple delivery servers. Each Sitecore instance/cluster will need to provide a key to identify the owner of each document. These keys are set in App_Config/Include/Sitecore.Analytics.Tracking.config. Using the host name is sufficient, although any string may be used for the cluster name.The solution for this problem can be found at https://kb.sitecore.net/articles/965127[code language="xml"]<setting name="Analytics.ClusterName" value="siteHostName" />[/code]If you started using the site with an empty string for this setting, the existing Mongo databases will need to be dropped and recreated (automatically) in order for the Cluster Name to take effect.
Backbone javascript error
This only happened after I installed the Launch Sitecore module, but it is worth noting. Click on the Create button on the EXM Start Page, choose a one-time message, select a template and enter a message name. Clicking on the Create button in this dialog resilts in an error in backbone:
The solution for this problem can be found at https://community.sitecore.net/developers/f/10/p/2623/7709#7709. The casing of the linkManager Urls and the javscript that uses those values need to be in sync with one another.[code language="xml" highlight="4"] <linkManager> <providers> <add name="sitecore"> <x:attribute name="lowercaseUrls">true</x:attribute> </add> </providers></linkManager>[/code]If lowercaseUrls is true, this script needs to be fixed:\Website\sitecore\shell\client\Applications\ECM\EmailCampaign.Client\Dialog\MessageCreationDialogBase.jsSetting lowercaseUrls to false may fix this problem, but it may also cause new errors to arise. I left the value as true and fixed the code that was failing as a result.There is a switch that expects specific casing:[code language="xml" highlight="2,5,8"]switch (createType) { case "ExistingTemplate": this.createExistingTemplate(contextApp, eventInfo); break; case "ExistingPage": this.createExistingPage(contextApp, eventInfo); break; case "ImportHtml": this.createImportHtml(contextApp); break; default:}[/code]It needs to be changed so the casing is ignored:[code language="xml" highlight="1,2,5,8"]switch (createType.toLowerCase()) { case "existingtemplate": this.createExistingTemplate(contextApp, eventInfo); break; case "existingpage": this.createExistingPage(contextApp, eventInfo); break; case "importhtml": this.createImportHtml(contextApp); break; default:}[/code]With all of these fixes in place the module will behave as expected. Happy coding!