2

I've written a custom bucket action to set the path based on a template date field, rather than the created date. I based this information off this blog: http://techitpro.com/uncategorized/sitecore-bucket-structure-item-field-value-based/

On creation, the template date field is set via a standard value to today's date, but this could be changed on edit. I found an old article asking about this: https://stackoverflow.com/questions/32612278/sitecore-8-sync-a-bucket-item-on-save. The original answer mentioned using the BucketManager.Sync function, which would sync the entire bucket, but a comment suggested there was a way to sync a single item and have its path alter like the entire bucket sync had been done.

Since this bucket is going to contain thousands of items, I'd like to avoid syncing the whole bucket on save each time. Is syncing a single item a feasible option in Sitecore 9.1.1, or is that not advisable?

2

You can achieve this by programmatically moving the bucketed item to the root of the bucket with the BucketManager. Doing this will force it to reevaluate the bucket rules and reorganize it:

BucketManager.MoveItemIntoBucket(bucketedItem, bucketItem);

In our solutions, we typically create an item:saved event handler to do this automatically:

using Sitecore.Buckets.Managers;
using Sitecore.Buckets.Util;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Events;
using System;
using System.Text.RegularExpressions;

namespace Custom.Events.ItemSaved
{
    public class ReorganizeBucketedItemInBucket
    {
        public void OnItemSaved(object sender, EventArgs args)
        {
            var bucketedItem = Event.ExtractParameter(args, 0) as Item;

            // If we don't have an item or we're not saving in the master DB, ignore this save
            if (bucketedItem == null || !"master".Equals(bucketedItem.Database?.Name, StringComparison.OrdinalIgnoreCase))
                return;

            if (!bucketedItem.TemplateID.Equals(new ID("{bucketed-item-template-id}"))) return;

            var itemChanges = Event.ExtractParameter(args, 1) as ItemChanges;

            // If there were no changes or the changes didn't include the date field, ignore this save
            if (itemChanges == null || !itemChanges.HasFieldsChanged || !itemChanges.IsFieldModified(new ID("{field-id-of-date-field}")))
                return;

            Item bucketItem = bucketedItem.GetParentBucketItemOrParent();

            // If this item isn't in a bucket (or is in a bucket of another, unexpected type), ignore it
            if (bucketItem == null) return;

            Item parent = bucketedItem.Parent;
            BucketManager.MoveItemIntoBucket(bucketedItem, bucketItem);

            // Delete empty ancestor bucket folders
            while (parent != null && !parent.HasChildren && parent.TemplateID == BucketConfigurationSettings.BucketTemplateId)
            {
                Item tempParent = parent.Parent;
                parent.Delete();
                parent = tempParent;
            }
        }
    }
}

And don't forget your patch config, of course:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <events>
            <event name="item:saved">
                <handler type="Custom.Events.ItemSaved.ReorganizeBucketedItemInBucket, Custom.Events" method="OnItemSaved"></handler>
            </event>
        </events>
    </sitecore>
</configuration>
  • Just implemented this, Dan, and it works great. One tweak I made from something I saw before, instead of using ancestor or self, I found this extension to get the top level bucket item: Item bucketItem = bucketedItem.GetParentBucketItemOrParent(); – Ken McAndrew Sep 27 at 1:35
  • Thanks for that little detail! I've updated the code to simplify it. – Dan Sinclair Sep 27 at 2:34
  • Dan, I may blog about this in the near future and I'll be sure to reference this for credit. I made an additional change to make the template/field configurable via the config. Which led me to branching out to updating my custom bucket rules to add those kinds of features as well. Thanks again for your help! – Ken McAndrew Sep 27 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.