Tag Archives: Pipelines

Un-tangling Sitecore configuration includes

I recently worked on a project that used SlowCheetah (XML Transforms) and Octopus variable substitution to modify the custom Sitecore include files.

It proved difficult to determine what the Sitecore configuration was in each environment, especially for the content delivery servers, as it was not possible to call showconfig.aspx.

Solution

Each time the application starts, it writes out the contents of the merged Sitecore configuration to a file in the logs folder. The file name contains the instance name, date and time created. So in addition to seeing the current configuration, you can also see how it changes over time (very useful after a deploy where nothing works).

Get the merged Sitecore configuration

It turned out to be very simple to implement, as it only takes one line of code to get the merged Sitecore configuration:

XmlDocument xmlDocument = Sitecore.Configuration.Factory.GetConfiguration();

Create a custom pipeline processor class

Create a processor for the initialize pipeline, so each time Sitecore is started the processor will be called to ensure that the configuration is saved. Create a public class with a public member called Process, which accepts a parameter of type PipelineArgs. The code below is all that is needed.

namespace Exmaple
{
  public class SaveSitecoreConfiguration
    {
        public void Process(PipelineArgs args)
        {
            string fullPath=string.Empty;
            try
            {
                XmlDocument configuration = Factory.GetConfiguration();
                string filename = string.Format("SitecoreConfiguration.{0}.{1}.xml", DateTime.Now.ToString("yyyyMMdd-hhmm"), Sitecore.Configuration.Settings.InstanceName);
                string logFolder = Sitecore.Configuration.Settings.LogFolder;

                // Is it a relative or virtual folder ?? could be a configured to point at an physical directory
                if (!Directory.Exists(logFolder))
                {
                    logFolder = HttpContext.Current.Server.MapPath(logFolder);
                }
                

                fullPath = Path.Combine(logFolder, filename);
                configuration.Save(fullPath);

            }
            catch (System.NotSupportedException supportedException)
            {
                Sitecore.Diagnostics.Log.Error(string.Format("Error saving sitecore configuration, path:{0}", fullPath), supportedException, this);
            }
            catch (Exception exception)
            {
                Sitecore.Diagnostics.Log.Error("Error saving sitecore configuration", exception, this);
            }
        }

    }
}

Configuration Changes

The processor has to be added to the initialize pipeline, I would recommend you create an include file to achieve this, but for the sake of clarity I have added it directly to the web.config, see below.

example

Now every-time Sitecore is started it writes out the configuration, so it is easy to get the configuration and monitor how it changes for all environments over time.

I hope this helps you untangle the Sitecore includes which at times can be a nightmare.

How to suspend sitecore schedule publishing – aborting the publish pipeline is not enough, it requires an exception!

The customer wanted the ability to suspend scheduled publishing, but could still make manual publishes (i.e. started from the Sitecore client).

Each time a publish is started it runs the publish pipeline. Therefore it is possible to insert a custom pipeline step at the beginning (see below) to do the following:

  1. Identify if it was a scheduled publish
  2. Check if a check-box in Sitecore is ticked
  3. If both conditions are met – abort the publish pipeline to stop the publish

publish pipeline

Unfortunately aborting the publish pipeline is not enough 😦

In the initial code I would abort the pipeline using AbortPipeline() (see below) as I assumed this was enough to stop the publish. The pipeline was aborted and no items were published, but the code that starts the pipeline still updated the properties table indicating that the publish had succeeded:-(

code

Side affect

This had the side effect that when the schedule publishing was enabled again, any items that were modified or created whist the publishing was disabled would not be published as when scheduled publishing was resumed Sitecore believed that they had already been published.

Solution

After checking the code using reflector I determined if I threw an exception, it would ensure that the properties table was not updated. So the publish was completely cancelled, and when scheduled incremental publishing was resumed it will publish all the items that have been modified since the last successful publish, and not since the last aborted publish.

How to identify a scheduled publish

Not the nicest solution but it works! I check the publish context user which can have the following values:

  1. The user logged into sitecore – If publish is started from the Sitecore client
  2. sitecore\Anonymous – if the publish is started by the scheduler

If the value is sitecore\Anonymous I know that it is a scheduled publish.

is schedules

 

 

 

SPEAK – Sitecore concept change and pipelines

A major concept change from sheer UI to SPEAK; is that continuation/control flow has moved from the server to the client. Now the client is responsible for control flow/state validation and the server is ideally responsible for answering simple/stateless requests.

Effectively a lot of server side C# code is moving to JavaScript, and to help with the complexity and to mirror the functionality/concepts available server side, Sitecore has introduced as part of the SPEAK framework client-side pipelines.

Client Pipelines

This is a very brief introduction and I will go into more detail in follow up post.

  1. A pipeline is a set of one or more steps that can be executed in a specific order; each step shares the same context.
  2. Each step can change the context and pass it to the next step until all steps have been completed, and or the pipeline is aborted.
  3. Each step can contain both client and server side logic or just client side logic.

The diagram below illustrates a simple pipeline that is executed when a button is clicked.

Pipeline

Example

So what can we use pipeline for? well one example could be when you delete an item, the idea is to keep each step as short and sweet as possible:

  1. Step 1 – Can Delete – check if the current user has the required permissions to delete the item.
  2. Step 2 – Can Lock – the item might be locked
  3. Step 3 – Confirm – prompt the user to ensure they really want to delete the item.
  4. Step 4 – Check Clone Links – as you have to warn the user that any cloned items will become real items.
  5. Step 5 – Execute – delete the item
  6. Step 6 – Has links – show the broken link dialog to fix any broken links
  7. Step 7 – Un-clone items.

Limitations

Unfortunately the current implementation does not provide the ability to define the order the steps are executed in, using a configuration file or the web.config. The order is defined by a property called priority that is defined within the JavaScript itself, see the code below.

define(["sitecore"], function (Sitecore) {
 Sitecore.Pipelines.MyFirstPipeline = Sitecore.Pipelines.MyFirstPipeline ||
                                      new Sitecore.Pipelines.Pipeline("MyFirstPipeline");
 var myFirstPipeline =
 {
   priority: 1,
   execute: function (context) {
     console.log("My first pipeline");
   }
 };
 Sitecore.Pipelines.ValidateMessagePageLoad.add(myFirstPipeline);
});

There are number drawbacks:

  1. Each step needs to know about other steps in order to be called in the appropriate sequence.
  2. Difficult to see a clear picture for a Pipeline (in which order steps are executed).
  3. If you want to insert/remove an extra step it an existing Sitecore speak pipeline you have to modify Sitecore’s source code.
  4. It increases the complexity of upgrade.

Hope

I hope that future version of SPEAK will support declarative declaration of pipeline steps, similar to what is available server side (i.e. pipelines defined in the web.config and or include configuration files).

My next post will go into more detail about how to create and initiate pipelines, hope you enjoyed my first ever post, Alan