Home » Clone » Chain Source and Clone Items Together in Sitecore Workflow

Chain Source and Clone Items Together in Sitecore Workflow

Sitecore Technology MVP 2016
Sitecore MVP 2015
Sitecore MVP 2014

Enter your email address to follow this blog and receive notifications of new posts by email.

Two months ago, I worked on a project where I had to find a solution to chain source Items and their clones together in Sitecore workflow — don’t worry, the clone Items were “locked down” by being protected so content authors cannot make changes to content on the clones — the clones serve as content copies of their source Items for a multi-site solution in a single Sitecore instance.

After some research, a few mistakes — well, maybe more than a few 😉 — and massive help from Oleg Burov, Escalation Engineer at Sitecore USA, I put together a subclass of Sitecore.Workflows.Simple.Workflow — this lives in Sitecore.Kernel.dll — similar to the following:

using Sitecore.Data.Items;
using Sitecore.Workflows;
using Sitecore.Workflows.Simple;

namespace Sitecore.Sandbox.Workflows.Simple
    public class ChainSourceClonesWorkflow : Workflow 
        public ChainSourceClonesWorkflow(string workflowID, WorkflowProvider owner)
            : base(workflowID, owner)

        public override WorkflowResult Execute(string commandID, Item item, string comments, bool allowUI, params object[] parameters)
            WorkflowResult result = base.Execute(commandID, item, comments, allowUI, parameters);
            foreach (Item clone in item.GetClones())
                base.Execute(commandID, clone, comments, allowUI, parameters);

            return result;

The Execute() method above basically moves the passed Item through to the next workflow state by calling the base class’ Execute() method, and grabs all clones for the passed Item — each are also pushed through to the next workflow state via the base class’ Execute() method.

Workflow instances are created by Sitecore.Workflows.Simple.WorkflowProvider. I created the following class to return an instance of the ChainSourceClonesWorkflow class above:

using Sitecore.Workflows;
using Sitecore.Workflows.Simple;

namespace Sitecore.Sandbox.Workflows.Simple
    public class ChainSourceClonesWorkflowProvider : WorkflowProvider
        public ChainSourceClonesWorkflowProvider(string databaseName, HistoryStore historyStore)
            : base(databaseName, historyStore)

        protected override IWorkflow InstantiateWorkflow(string workflowId, WorkflowProvider owner)
            return new ChainSourceClonesWorkflow(workflowId, owner);

I then replaced the “out of the box” WorkflowProvider with the one defined above using the following configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
      <database id="master">
        <workflowProvider type="Sitecore.Workflows.Simple.WorkflowProvider, Sitecore.Kernel">
          <patch:attribute name="type">Sitecore.Sandbox.Workflows.Simple.ChainSourceClonesWorkflowProvider, Sitecore.Sandbox</patch:attribute>

Let’s take this for a spin!

I first started with a source and clone in a “Draft” workflow state:


Let’s push the source — and hopefully clone 😉 — through to the next workflow state by submitting it:


As you can see, both are “Awaiting Approval”:


Let’s approve them:


As you can see, both are approved:


If you have any thoughts or comments on this, or know of ways to improve the code above, please drop a comment.

Also, keep in mind the paradigm above is not ideal when content authors are able to make content changes to clones which differ from their source Items. In that scenario, it would be best to let source and clone Items’ workflow be independent.



  1. Alen Pelin says:

    I suggest using “set” namespace instead of “patch” as it is more clean and easy to read:


Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: