Bucket item resolver

Sitecore item bucket - Customisation

The intent of this article it to customise the item bucket.

  1. Override Link Provider: override link provided to remove the bucket path from bucket item's path.
  2. Bucket item resolver : custome sitecore pipeline to resolve the bucket item without bucket path in requested URL.

Bucket Link Manager - Override Link provider

As shown in our previous article once we have bucketing in place item will be found in respective bucket path. 


















Figure : Item path in bucket.

As you can see in above screenshot item Ajay is available in path "/sitecore/content/Home/People Directory/a/Ajay" so this item can be browsed in as "http://sitename/people directory/a/ajay"

okay so now let's assume we don't want this item's link to have bucket path in it e.g "http://sitename/people directory/ajay", to achieve this we need to override the sitecore link provider and patch it in sitecore.config. 

File: BucketLinkManager.cs

using Sitecore.Buckets.Managers;
using Sitecore.Buckets.Extensions;
using Sitecore.IO;
using Sitecore.Links;

namespace kbsitecore.Web.Cms.Extensions
{
    public class BucketLinkManager : LinkProvider
    {
        public override string GetItemUrl(Sitecore.Data.Items.Item item, UrlOptions options)
        {
            if (BucketManager.IsItemContainedWithinBucket(item))
            {
                var bucketItem = item.GetParentBucketItemOrParent();
                if (bucketItem != null && bucketItem.IsABucket())
                {
                    var bucketUrl = base.GetItemUrl(bucketItem, options);
                    if (options.AddAspxExtension)
                    {
                        bucketUrl = bucketUrl.Replace(".aspx", string.Empty);
                    }

                    return FileUtil.MakePath(bucketUrl, item.Name).Replace(" ", "-") +
                            (options.AddAspxExtension ? ".aspx" : string.Empty);
                }
            }
                        
            return Sitecore.StringUtil.EnsurePostfix('/', base.GetItemUrl(item, options));
        }
    }
}

To patch the above code we need to add one patch config file
File: Sitecore.BucketLinkManager.config

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"
  <sitecore>
    <linkManager>
      <providers>
        <add name="sitecore">
          <patch:attribute name="type">kbsitecore.Web.Cms.Extensions.BucketLinkManager, kbsitecore.Web.Cms</patch:attribute>
        </add>
      </providers>
    </linkManager>
  </sitecore>
</configuration

Note :  Put the above patched config file in include folder under the App_config

Now we are done with customisation to Link Provider to remove the bucket path  from the bucket item path, now sitecore will always generate link to bucket item Ajay  without bucket path "/en/People-Directory/Ajay" but as we now this item does not exists in sitecore at "/en/People-Directory/Ajay" path so item will not be resolved and we will get 404 page. To over come this problem we need to resolve the bucket item by writing own sitecore pipeline BucketItemResolver

Bucket item resolver

To resolve the custom bucket link we need to add one own customised sitecore pipeline to resolve this bucket item.

File:  BucketItemResolver.cs

using System;
using Sitecore.Pipelines.HttpRequest;
using Sitecore;
using Sitecore.ContentSearch;
using System.Configuration;
using Sitecore.ContentSearch.SearchTypes;
using System.Linq;

namespace Kbsitecore.Web.Cms
{
    public class BucketItemResolver : HttpRequestProcessor
    {
        public override void Process(HttpRequestArgs args)
        {
            if (Context.Item != null || Context.Database == null || args.Url.ItemPath.Length == 0)
                return;
            var requestUrl = args.Url.ItemPath.TrimEnd('/');

            var index = requestUrl.LastIndexOf('/');
           
            var bucketPath = requestUrl.Substring(0, index);
            bucketPath = MainUtil.DecodeName(bucketPath);
            var bucketItem = args.GetItem(bucketPath);
            if (bucketItem != null)
            {
                var itemName = requestUrl.Substring(index + 1);
                using (var searchContext = ContentSearchManager.GetIndex("sitecore_web_index").CreateSearchContext())
                {
                    Sitecore.Data.ID bucketTemplateID = new Sitecore.Data.ID(new Guid("{58EEFA3B-EB4C-49B3-B1E8-A75892062E76}"));
                    var result = searchContext.GetQueryable<SearchResultItem>().Where(
                                x => x.TemplateId == bucketTemplateID && (x.Name == itemName || x.Name == itemName.Replace("-", " "))).FirstOrDefault();
                    
                    if (result != null)
                    {
                        var item = result.GetItem();
                        if (item.Language == Context.Language)
                        {
                            Context.Item = result.GetItem();
                        }
                        else
                        {
                            var langItem = Sitecore.Context.Database.GetItem(result.ItemId, Context.Language);
                            if (langItem != null)
                            {
                                Context.Item = langItem;
                            }
                        }

                    }
                }
            }
        }
    }
}



Okay now we have are pipeline ready lets write on patch it with sitecore.config

File. Sitecore.BucketItemResolver.config 


<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <httpRequestBegin>
        <processor patch:before="processor[@type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']" type="Kbsitecore.Web.Cms.BucketItemResolver, Kbsitecore.Web.Cms" />
      </httpRequestBegin>
    </pipelines>
  </sitecore>

</configuration>

Note : You need to put the above patched Sitecore.BucketitemResolver.confgi in include folder

Once you have this config in place and publish the website you will be able to access your bucket item with out bucket path. 


Figure: Item bucket resolved with bucket path in the URL

No comments:

Post a Comment