An Introduction to Sitecore Pipelines

What is a Sitecore Pipeline?

In Sitecore pipelines describe a series of discrete steps that are taken to achieve some objective.  If you think about writing code to handle an HTTP request for example you could create a monolithic class that does the job from end to end; however the pipeline approach is a number of classes that can be invoked in order.  First do this and then do that etc. 

There are many Pipelines in Sitecore.  You can view existing pipelines and the processors that they call using Sitecore Rocks in Visual Studio.  Right click on the site connection and choose Manage. Click on the Pipelines tab in the Visual Studio edit pane.  Click on one of the listed pipelines to see all the processors that are executed as part of the pipeline.  There are pipelines with a single processor at one end of the scale to the httpRequestBegin pipeline with 45 distinct steps at the other.

Why are they useful?

Thinking about the monolithic class above it would be very difficult to maintain or modify, It would also be truly massive.  So modularising it would make it much easier to maintain. 

It also makes it much easier to customise.  For example, if we consider a pipeline that has three processors it might be drawn something like

To add to the existing functionality we could include a new step like

Where we add some custom function after Step 1 and before Step 2. 

We could also replace an existing step completely

How are they defined?

Pipelines are defined using XML in sitecore.config.  In the example below we can see the httpRequestEnd pipeline definition.  The three processors are called in the order in which they are listed.  A parameters object is passed between them to provide continuity.  The final processor is also receiving four additional parameters from the config file.

<?xml version="1.0" encoding="utf-8"?>
<sitecore database="SqlServer" xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:security="http://www.sitecore.net/xmlconfig/security/">
…
<pipelines>   
… 
<httpRequestEnd>
      <processor type="Sitecore.Pipelines.PreprocessRequest.CheckIgnoreFlag, Sitecore.Kernel" />
      <processor type="Sitecore.Pipelines.HttpRequest.EndDiagnostics, Sitecore.Kernel" role:require="Standalone or ContentManagement" />
      <!--<processor type="Sitecore.Pipelines.HttpRequest.ResizePicture, Sitecore.Kernel"/>-->
      <processor type="Sitecore.Pipelines.HttpRequest.StopMeasurements, Sitecore.Kernel">
        <ShowThresholdWarnings>false</ShowThresholdWarnings>
        <TimingThreshold desc="Milliseconds">1000</TimingThreshold>
        <ItemThreshold desc="Item count">1000</ItemThreshold>
        <MemoryThreshold desc="KB">10000</MemoryThreshold>
      </processor>
    </httpRequestEnd>
…
    </pipelines>
…
  </sitecore>

How can I work with Sitecore Pipelines?

Existing Sitecore pipelines can be customised as outlined above and it is also possible to create a brand new pipeline from scratch

Customise existing Pipelines

First thing to do is to create a configuration patch to add the new processor class into the pipeline at the desired location.  As you can see from the code it is possible to pass variables to the processor.  Here we are adding a processor called NewsArticleLogEntryProcessor into the httpRequestBegin pipeline after the ItemResolver

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <httpRequestBegin>
        <processor type="Fourbyclub.CustomCode.CustomCode.Pipelines.httpRequestBegin.NewsArticleLogEntryProcessor,Fourbyclub.CustomCode" patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']">
          <NewsArticleTemplateID>{B871115E-609F-44BB-91A4-A37F5E881CA6}</NewsArticleTemplateID>
        </processor> 
      </httpRequestBegin>
    </pipelines>
  </sitecore>
</configuration>

Then we need to create the processor.  Inherit the HttpRequestProcessor and Implement the Process method.  All we are doing here is writing to the log if the requested item is a NewsArticle.

namespace Fourbyclub.CustomCode.CustomCode.Pipelines.httpRequestBegin
{
    using Sitecore.Pipelines.HttpRequest;
    using Sitecore.Diagnostics;

    // TODO: \App_Config\include\NewsArticleLogEntryProcessor.config created automatically when creating NewsArticleLogEntryProcessor class.

    public class NewsArticleLogEntryProcessor : HttpRequestProcessor
    {
        
        // Declare a property of type string:
        private string _newsArticleTemplateID;
        public string NewsArticleTemplateID { get { return _newsArticleTemplateID; } set { _newsArticleTemplateID = value; } }

        public override void Process(HttpRequestArgs args)
        {
            Assert.ArgumentNotNull(args, "args");
            if ((Sitecore.Context.Item != null) && (!string.IsNullOrEmpty(_newsArticleTemplateID)))
            {
                Assert.IsNotNull(Sitecore.Context.Item, "No item in parameters");
                // use util to get id from string property
                if (Sitecore.Context.Item.TemplateID == Sitecore.MainUtil.GetID(_newsArticleTemplateID))
                {
                    // view in log file later, so add FourbyclubCustomCode
                    Log.Info(string.Format("FourbyclubCustomCode: News Article requested is {0} and the item path is {1}", Sitecore.Context.Item.DisplayName, Sitecore.Context.Item.Paths.FullPath), this);
                }
            }
        }

    }
}

Create a new Pipleline

To create and new pipeline is a little more work but still very simple.  The first thing to do is to declare the pipeline with a configuration patch

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <logWriter>
        <processor type="Fourbyclub.CustomCode.CustomCode.Pipelines.logWriter.logWriterProcessor,Fourbyclub.CustomCode" />
      </logWriter>
    </pipelines>
  </sitecore>
</configuration>

The XML above will create a pipeline called logWriter that has a single processor called logWriterProcessor, which will be in the Fourbyclub.CustomCode.dll.

Pipelines must pass a PipelineArgs object to each processor as it is called so that needs to be defined

using Sitecore.Pipelines;

namespace Fourbyclub.CustomCode.CustomCode.Pipelines.logWriter
{
    public class LogWriterPipelineArgs : PipelineArgs
    {
        public string LogMessage { get; set; }
    }
}

At least one processor is needed to do the work of our pipeline

using Sitecore.Diagnostics;

namespace Fourbyclub.CustomCode.CustomCode.Pipelines.logWriter
{
    public class logWriterProcessor
    {
        public void Process(LogWriterPipelineArgs args)
        {
            Log.Info(string.Format("FourbyclubCustomCode: The message was {0}", args.LogMessage), this);
        }
    }
}

Finally we need to invoke the pipeline in our code somewhere.  Instantiate the LogWriterPipelineArgs and set the LogMessage.  Then call CorePipeline.Run and pass it the name of the pipeline and the args.object

var pipelineargs = new LogWriterPipelineArgs();
pipelineargs.LogMessage = "Requested item is not a News Article";
CorePipeline.Run("logWriter", pipelineargs);

Conclusion

Thank you for reading and I hope that this short introduction to Sitecore Pipelines has shown the power of pipelines to customise Sitecore and help to build maintainable code.  However we should always check if there is a way we can implement something using existing Sitecore functionality rather than going for a pipeline as a first resort. As with any customisation does each pipeline or processor added have a potential to increase the challenge of Sitecore upgrades?

Training for your Sitecore project

To mis-quote Benjamin Franklin ‘By failing to train you are training to fail”.  You can provide the best tools in the world but unless people know how to use them, they are useless.  And the more complex the tool the more apparent that becomes.  I think Sitecore is a simple, intuitive tool but then I have been delivering training on Sitecore for eight years.  I’m now familiar with the system. But I do know that at first sight it can appear overwhelming.

So, how best to use training to mitigate risk in your Sitecore project, or any other for that matter? 

I recommend a three-phase approach starting as early as possible in the project.  If it is possible start before the vendor is decided.  Phase one is pretraining.  Phase two shortly before Go Live or UAT. And finally phase three is ongoing maintenance to allow for staff churn, new features etc.

Let’s look at each phase in a bit more detail. 

Phase One/Pretraining

Phase one is the first tranche of training.  As stated above it should be undertaken early in the project.  Assuming you are starting the project by selecting the vendor for a software project; once you have a short list consider sending key stakeholders to classroom training on each of your shortlisted vendors.  While it may be considered an unnecessary cost it will provide a good insight into the real-world use of the various offerings.  And also consider that the cost of pretraining is insignificant compared to the cost of a failed project.

Once you have decided on a vendor, if they have not already, key business and technical staff should attend appropriate training for their role.  Selection should be based upon who will be working with the implementation partner.  Training at this early stage will equip the team with the skills to work with the implementer.  It also shows attendees the capabilities of the chosen platform; they know what to ask for. 

If an implementation partner hasn’t been selected yet training this early can also be useful in their selection.

Delivery for this tranche should be public classroom training, unless you have the numbers to make a private course worthwhile (hint 6+ staff is the tipping point from a public class to a private one).  Classroom training allows for questions to be asked and a good trainer can adapt the delivery to ensure the learning outcomes are achieved.

Phase two/Go Live

Phase two is where the bulk of your users receive training – this is because you are about to go live with your new website.  By now it should be possible to train on, or at least reference, your application as it will be implemented.  Various options are available.  eLearning, although to be fair I am not a fan of eLearning, it is too easy to click through and be distracted by other incoming tasks and emails without absorbing the information.  However, it is cheap and repeatable.  For business users, you could even consider bespoke eLearning.  While the initial cost is high you own the content and there are negligible ongoing costs plus it covers maintenance training or phase three.  Classroom training such as public courses will be generic and provide a good understanding of the features of the chosen application – it will probably be useful to have an internal follow up to familiarise business users with their application.  Developers should be fine with just a public course and some time to get to know the code.  It is, again, possible to get customized or completely bespoke training delivered in a classroom – where your lesson is about the application you are implementing within your organisation.  Delivery costs should be approximately the same as attending public courses but there will be development costs involved; how much will depend on the degree of customisation required

Phase three/Maintenance

Once your website is live and all the users and developers are trained, we move to phase three or maintenance.  Additional training maybe required if you upgrade the version of the application or introduce new features (depending on the enormity of the changes). 

Phase three training is primarily needed for staff churn.  Developers should start by attending the public courses and then learn peer to peer, consider pair programming here.  For business users it is beneficial to attend public classroom training to get the solid foundation to build on.  Just peer to peer onboarding, while tempting, can perpetuate bad habits and often leaves knowledge gaps in the real understanding of the application.  At the very least you need a set of learning objectives that must be ticked off preferably by your in-house super user.

Aceik is a Sitecore training provider.  We teach public courses around the country.  You can view the public schedule here: Upcoming Courses New courses are being worked on constantly so if you do not see what you want please enquire here or email David Newman at the link below.  We also provide custom or private training email David Newman in the first instance or if you are an Aceik customer already contact your account manager.