Archive

Archive for October, 2014

WFFM publishing with related item, fixing missing form elements

29/10/2014 2 comments

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

29-10-2014 11-22-29

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.

29-10-2014 11-23-32

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.

Advertisements
Categories: C#, Sitecore, WFFM Tags: , ,

Escaping dashes/“-” in Sitecore Queries. Datasource query Update

29/10/2014 5 comments

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

 

 

Categories: C#, Sitecore Tags: , ,

Launch Mongo DB with Sitecore Pipelines

01/10/2014 2 comments

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

http://briancaos.wordpress.com/2014/10/01/sitecore-and-xdb-setting-up-mongodb-on-your-developer-machine/

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.

Categories: C#, MongoDB, Sitecore Tags: , ,