Home » Clone » Rename Sitecore Clones When Renaming Their Source Item

Rename Sitecore Clones When Renaming Their Source Item

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.

Earlier today I discovered that clones in Sitecore are not renamed when their source Items are renamed — I’m baffled over how I have not noticed this before since I’ve been using Sitecore clones for a while now :-/

I’ve created some clones in my Sitecore instance to illustrate:

clones-not-renamed-yet

I then initiated the process for renaming the source item:

clones-renaming

As you can see the clones were not renamed:

clones-not-renamed-sad-face

One might argue this is expected behavior for clones — only source Item field values are propagated to its clones when there are no data collisions (i.e. a source Item’s field value is pushed to the same field in its clone when that data has not changed directly on the clone — and the Item name should not be included in this process since it does not live in a field.

Sure, I see that point of view but one of the requirements of the project I am currently working on mandates that source Item name changes be pushed to the clones of that source Item.

So what did I do to solve this? I created an item:renamed event handler similar to the following (the one I built for my project is slightly different though the idea is the same):

using System;
using System.Collections.Generic;

using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Events;
using Sitecore.Links;
using Sitecore.SecurityModel;

namespace Sitecore.Sandbox.Data.Clones
{
    public class ItemEventHandler
    {
        protected void OnItemRenamed(object sender, EventArgs args)
        {
            Item item = GetItem(args);
            if (item == null)
            {
                return;
            }

            RenameClones(item);
        } 

        protected virtual Item GetItem(EventArgs args)
        {
            if (args == null)
            {
                return null;
            }

            return Event.ExtractParameter(args, 0) as Item;
        }

        protected virtual void RenameClones(Item item)
        {
            Assert.ArgumentNotNull(item, "item");
            using (new LinkDisabler())
            {
                using (new SecurityDisabler())
                {
                    using (new StatisticDisabler())
                    {
                        Rename(GetClones(item), item.Name);
                    }
                }
            }
        }

        protected virtual IEnumerable<Item> GetClones(Item item)
        {
            Assert.ArgumentNotNull(item, "item");
            IEnumerable<Item> clones = item.GetClones();
            if (clones == null)
            {
                return new List<Item>();
            }

            return clones;
        }

        protected virtual void Rename(IEnumerable<Item> items, string newName)
        {
            Assert.ArgumentNotNull(items, "items");
            Assert.ArgumentNotNullOrEmpty(newName, "newName");
            foreach (Item item in items)
            {
                Rename(item, newName);
            }
        }

        protected virtual void Rename(Item item, string newName)
        {
            Assert.ArgumentNotNull(item, "item");
            Assert.ArgumentNotNullOrEmpty(newName, "newName");
            if (!item.Access.CanRename())
            {
                return;
            }
            
            item.Editing.BeginEdit();
            item.Name = newName;
            item.Editing.EndEdit();
        }
    }
}

The handler above retrieves all clones for the Item being renamed, and renames them using the new name of the source Item — I borrowed some logic from the Execute method in Sitecore.Shell.Framework.Pipelines.RenameItem in Sitecore.Kernel.dll (this serves as a processor of the <uiRenameItem> pipeline).

If you would like to learn more about events and their handlers, I encourage you to check out John West‘s post about them, and also take a look at this page on the
Sitecore Developer Network (SDN).

I then registered the above event handler in Sitecore using the following configuration file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <events>
      <event name="item:renamed">
        <handler type="Sitecore.Sandbox.Data.Clones.ItemEventHandler, Sitecore.Sandbox" method="OnItemRenamed"/>
      </event>
    </events>
  </sitecore>
</configuration>

Let’s take this for a spin.

I went back to my source item, renamed it back to ‘My Cool Item’, and then initiated another rename operation on it:

clones-renaming

As you can see all clones were renamed:

clones-renamed

If you have any thoughts/concerns on this approach, or ideas on other ways to accomplish this, please share in a comment.

Advertisement

Comment

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: