Archive
WFFM publishing with related item, fixing missing form elements
When adding a form to a page via the page editor, Sitecore registers a reference to form element, so when you publish you can check the publish related Items checkbox, and you would expect the form to be visible on your CD-server
However WFFM places all elements in the form as children to form element itself, and these are not added to the publishing queue because they are not related to page where the form was first added.
So when publishing the form is correctly being published, but the fields for the forms isn’t moved from the master database to web database and the form is of course then not rendered out.
As always Sitecore has a pipeline, that you can hook into in this case the “getItemReferences” this pipelines, resolves related items and adds them to the publishing queue. So hooking into this and adding child elements for forms is actually quite easy.
public class GetFormChildElementProcessor : GetItemReferencesProcessor { private readonly ID _formTemplateId = new ID("{FFB1DA32-2764-47DB-83B0-95B843546A7E}"); protected override List<Item> GetItemReferences(PublishItemContext context) { List<Item> relatedformItems = new List<Item>(); if(!context.Result.ReferredItems.Any()) return relatedformItems; Database database = context.PublishContext.PublishOptions.SourceDatabase; var formItems = context.Result.ReferredItems.Where(i=>IsDerived(database.GetItem(i.ItemId).Template, _formTemplateId)).ToList(); foreach (var form in formItems) { var formChildren = form.ChildEntries; foreach (var child in formChildren) { relatedformItems.Add(database.GetItem(child.ItemId)); } } return relatedformItems; } public bool IsDerived(TemplateItem template, ID templateId) { if (!(template.ID == templateId)) { return Enumerable.Any<TemplateItem>(template.BaseTemplates, baseTemplate => IsDerived(baseTemplate,templateId)); } return true; } }
And now register the processor in the web.config under /configuration/sitecore/pipelines/getItemReferences add it at the end.
<processor type="PT.Framework.PublishForm.GetFormChildElementProcessor, PT.Framework.PublishForm"/>
Now all the child elements to items the derives from the form element will be added to the publishing queue.
Escaping dashes/“-” in Sitecore Queries. Datasource query Update
This is actually more an update to the post Query in Datasource location I wrote some while ago. As I was working on a new solution I often saw an error with “unterminated literal string in Query”. In my case it was actually quite simple because an item name include a dash “-”, which is an illegal character in a query, the solution is to escape the part of the the path that contains the “-”. you escape it by adding “#” around the word, see the example below.
query:/sitecore/content/some/path-with-dash/becomes
query:/sitecore/content/some/#path-with-dash#/becomes
The code to fix this is simple and Anders Laub wrote the version you see below.
private string EscapeItemNamesWithDashes(string queryPath) { if (!queryPath.Contains("-")) return queryPath; var strArray = queryPath.Split(new char[] { '/' }); for (int i = 0; i < strArray.Length; i++) { if (strArray[i].IndexOf('-') > 0) strArray[i] = "#" + strArray[i] + "#"; } return string.Join("/", strArray); }
The source code for using queries is also available on github , with the above enhancement.
https://github.com/istern/RenderingsDatasources
Launch Mongo DB with Sitecore Pipelines
My colleague Brian Pedersen recently wrote at blog post about setting up MongoDB and starting it up with a simple bat-file read it here
Combine the first step “download” mongo with starting a process as my other colleague Anders Laub showed how to do in his crush png post here http://laubplusco.net/crush-png-in-sitecore/
Then you have a pipeline that can start mongo if it isn’t running.
First lets create a new custom pipeline to start a mongo instance if none is running
First the new “startmongodb” pipeline
<startmongodb> <processor type="Mongo.PingMongoDB, Mongo" /> <processor type="Mongo.StartMongoDB, Mongo" /> </startmongodb>
Replace string constant with more generic method, First a processor that test to see if mongo is allready running.
public class PingMongoDB { public void Process(PipelineArgs args) { Log.Audit("Pinging Mongo", this); //Replace with connectionstring from config file var client = new MongoClient("mongodb://localhost"); var server = client.GetServer(); try { server.Ping(); Log.Audit("Mongo Allready running", this); args.AbortPipeline(); } catch (Exception) { Log.Audit("Mongo Not Running", this); } } }
Now to the start mongo processor
public class StartMongoDB { public void Process(PipelineArgs args) { var startInfo = new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, //Replace with path to your mongo FileName = "D:\\MongoDB\\bin\\mongod.exe", //Replace with path to your mongo datadrive Arguments = @"--dbpath sc75rev140429\Databases\MongoDBData", WindowStyle = ProcessWindowStyle.Hidden }; try { Log.Audit("Trying to start mongo",this); using (var exeProcess = System.Diagnostics.Process.Start(startInfo)) { exeProcess.WaitForExit(50); } Log.Audit("Mongo started", this); } catch (Exception exception) { Log.Error("Could not start mongo", exception, this); } } }
Finally we need to run the “startmongodb” pipeline when Sitecore Starts/Initialize so in
the initialize pipeline and at the end add
<processor type="Mongo.RunMongoPipeline, Mongo" />
code for this simple processor
public class RunMongoPipeline { public void Process(PipelineArgs arg) { CorePipeline.Run("startmongodb",new PipelineArgs()); } }
From the log we can now see if mongo isn’t runnnig and was started also there is now warnings in the log :
INFO AUDIT (default\Anonymous): Mongo Not Running
INFO AUDIT (default\Anonymous): Trying to start mongo
INFO AUDIT (default\Anonymous): Mongo started
so the follwing isn’t seen in the log which it would be if mongo wasn’t running
ERROR MongoDbDictionary.Store() has failed. Exception: Sitecore.Analytics.DataAccess.DatabaseNotAvailableException Message: Database not available Source: Sitecore.Analytics.MongoDB at Sitecore.Analytics.Data.DataAccess.MongoDb.MongoDbCollection.Execute(Action action, ExceptionBehavior exceptionBehavior) at Sitecore.Analytics.Data.DataAccess.MongoDb.MongoDbDictionary.Store(Object value)
What is left now is cleaning the code and use args for supplying the correct values instead of hardcoded strings. This is left as a free of charge excercise.