Sitecore has a pretty cool stuff called Bucketing which lets you store and manage huge amount of content items in one single container. I guess you already know what I’m talking about so I will skip explaining how to work with bucket items.
This post will explain how an orphan bucket folder will be removed dynamically removed when a bucketable item is deleted from the Sitecore tree using a custom event handler.
First, we will need to define our new custom event who should be placed into the item:deleted. This is the event that is raised when an item has been deleted. The subscription of the event is in the following way:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <events> <event name="item:deleted"> <handler type="Project.Website.Configuration.CleanupBucket, Project.Website" method="OnItemDeleted" /> </event> </events> </sitecore> </configuration>
Then we have to implement a class that will loop thought all the ancestors of the deleted item and will remove the bucket folders that are not having a bcuketable child item.
namespace Project.Website.Configuration { public class CleanupBucket { /// <summary> /// Called when [item deleted complete]. /// </summary> /// <param name="sender">The sender.</param> /// <param name="eventArgs">The <see cref="EventArgs"/> instance containing the event data.</param> protected virtual void OnItemDeleted(object sender, EventArgs eventArgs) { var sitecoreArgs = eventArgs as Sitecore.Events.SitecoreEventArgs; if (sitecoreArgs == null) return; var item = Sitecore.Events.Event.ExtractParameter(eventArgs, 0) as Item; if (item == null || item.IsABucket() || !item.IsItemBucketable()) return; var parentId = Sitecore.Events.Event.ExtractParameter(eventArgs, 1) != null ? Sitecore.Events.Event.ExtractParameter(eventArgs, 1).ToString() : null; var parentItem = !string.IsNullOrWhiteSpace(parentId) ? item.Database.GetItem(new ID(parentId)) : null; CleanupOrphanBucket(item, parentItem); } protected void CleanupOrphanBucket(Item item, Item currentParentItem = null) { Assert.IsNotNull(item, "item"); var parentItem = currentParentItem ?? item.Parent; if (parentItem == null || !parentItem.IsABucketFolder() || parentItem.Axes.GetDescendants().Any(child => !child.IsABucketFolder())) return; using (new Sitecore.SecurityModel.SecurityDisabler()) { var parentAncestor = parentItem.Parent; parentItem.Delete(); CleanupOrphanBucket(parentItem, parentAncestor); } } } }
Finally, verify that your merged configuration has your class into the <event> configuration node. Consider including this event also for the remove event handler (item:deleted:remote)
For more information, you can visit Sitecore Buckets.
Happy Sitecoring 😉