How to Make Custom Bucket Structure in Sitecore - Brimit Blog

Bucket instances have been introduced in Sitecore 7 as a solution to store millions of content items in one container. The Sitecore buckets allow avoiding issues with managing large numbers of items within the content tree, improving the Sitecore CMS performance.

Let us show you how to create a simple but useful customization for Sitecore buckets.

In order to migrate the Sitecore folder to bucket, click the ‘Bucket’ button on the configuration tab of the ribbon.

Note: items in the folder must be ‘Bucketable’ – corresponding checkbox must be checked on items’ standard values:

Turning Sitecore items into a bucket will take some time, after the process complete a new structure under ‘bucketed’ folder will be available:

(Check the ‘Buckets’ checkbox on the ‘View’ tab of the ribbon to see the structure, otherwise only the ‘There are hidden items in this container’ notification will be shown).

Why to display structure if buckets are not supposed to have structure? One of reasons is to allow users to select item stored in bucket with field like Droptree.

Sitecore Buckets display folders structure based on the items’ creation date. By default, Sitecore creates five nested folders: year/month/day/hour/minute. It is possible to customise the date-based structure in the Sitecore.Buckets.config file with the ‘BucketConfiguration.BucketFolderPath’ setting. The setting contains format string for DateTime.ToString(format) method. For example we may use only date for the structure:

<setting name="BucketConfiguration.BucketFolderPath" value="yyyy\/MM\/dd"/>

But in some cases date-based structure is not optimal. For example, when it is required to migrate existing folder to buckets and client is used to find items in plain list of items by item name. In this case it’s better to use structure based on items’ name or any other property.

There is a setting in Sitecore.Buckets.config file which defines how bucket item’s path will be resolved:

<setting name="BucketConfiguration.DynamicBucketFolderPath" value="Sitecore.Buckets.Util.BucketFolderPathResolver, Sitecore.Buckets"/>

At this point, it is possible to create custom path resolver and update the setting. For instance, in order to add path resolver based on two first letters of item name:

public class BucketFolderPathByNameResolver : IDynamicBucketFolderPath { public string GetFolderPath(Database database, string name, ID templateId, ID itemId, ID parentItemId, DateTime creationDateOfNewItem) { var foldersNames = name.ToCharArray().Where(Char.IsLetterOrDigit).Take(2).ToList(); if (foldersNames.Any()) { return string.Join(Constants.ContentPathSeperator, foldersNames); } // return default date-based path if something is wrong return creationDateOfNewItem.ToString(BucketConfigurationSettings.BucketFolderPath, CultureInfo.InvariantCulture); } }

and update Sitecore.Buckets.config:

<setting value="MyNamespace.BucketFolderPathByNameResolver, MyNamespace" name="BucketConfiguration.DynamicBucketFolderPath"></setting>

Go to the Sitecore bucket item, click ‘Sync’ on the buckets’ ribbon and the result will be a new bucketed items structure with two levels of folders, based on items’ names (Note: characters that are not letter or digit are filtered out to avoid inappropriate symbols in folder names).

This approach is a working solution, yet not a flexible one. It this case all buckets in Sitecore instance forced with specific structure.

There is a more flexible bucket management solution supported by Sitecore.

Go to ’/sitecore/system/Settings/Buckets/Item Buckets Settings’ and check the ‘Rules’ field. The field contains option to specify separate bucketing rules for different items. There’s an action titled ‘create the folder structure based on the name of the new bucketable item with this number of levels’ , but the problem with this action is that it will try to create folders with any char from item name including space and glyph what is not acceptable. Therefore, it’s recommended to create custom action for path resolving. First, use a class inherited from ‘Sitecore.Rules.Actions.RuleAction<T>’ for example:

public class ResolvePathBasedOnCleanName : RuleAction where T : BucketingRuleContext { public string Levels { get; set; } public override void Apply(T ruleContext) { Assert.ArgumentNotNull(ruleContext, "ruleContext"); int nestedFoldersCount; if (int.TryParse(Levels, out nestedFoldersCount)) { var foldersNames = ruleContext.NewItemName.ToCharArray().Where(Char.IsLetterOrDigit).Take(nestedFoldersCount).ToList(); if (foldersNames.Any()) { ruleContext.ResolvedPath = string.Join(Constants.ContentPathSeperator, foldersNames); } } else { Log.Warn("CreateItemNameBasedPath: Cannot resolve item path by this rule", this); } } }

Second, add a new Action to Sitecore folder ‘/sitecore/system/Settings/Rules/Definitions/Elements/Bucketing’ and set appropriate Type and Text.

Now return to ’/sitecore/system/Settings/Buckets/Item Buckets Settings’ item and chose new action for the Rule (e.g. select template of items that will be bucketed with the custom structure).

We believe this customization will make Sitecore bucket management easier for you! Please share your experience with Sitecore buckets!