Custom Alias Resolver for Sitecore media item


Working on different projects and different type of tasks is always give an opportunity to learn something new as with my last implementation we came across with a very different requirement where client ask us to make the media url’s more friendly as Sitecore content tree URL’s. Or in other words if I say they ask us to build something which look like a Content Page but render like a media item. And that media can be sections related (Means URL for that media can be manageable as content tree architecture) So here I am going to write what I have build so far to complete this task.

We have created a Data Template (Media Reference) type with Droptree field. Droptree field we provided to map the media item. My plan was to give an option to create a simple content item with Media Reference template type and map the media item into droptree field.

It was easy to create but now the task was render the mapped media item onto media reference page. Here what I already know there is no out of the box functionality available to achieve this I need to customize any of the Sitecore pipeline which actually run the Item URL but render the mapped media item.

After reading few articles I got the understanding that If I can create Custom Alias Resolver than I can achieve this and I started digging into Sitecore dll’s for Alias Resolver.

I have created a class CustomAliasResolver and inherited by HttpRequestProcessor.

After that I copied the code of Alias Resolver into this class and made the tweaks as per my need. See below code to achieve this –


public override void Process(HttpRequestArgs args)
        {
            Assert.ArgumentNotNull((object)args, "args");
            Database database = Context.Database;
            if (database == null)
            {
                Tracer.Warning((object)"There is no context database.");
            }
            else
            {
                Profiler.StartOperation("Resolve custom alias.");
                if (ProcessItem(args))
                {
                    if (Context.Item != null)
                    {
                        string mediaUrl = MediaManager.GetMediaUrl((MediaItem)Context.Item);
                        if (!string.IsNullOrEmpty(mediaUrl))
                        {
                            string handler = HandlerUtil.GetHandler(mediaUrl);
                            if (!string.IsNullOrEmpty(handler))
                            {
                                Context.Data.RawUrl = mediaUrl;
                                args.Context.RewritePath(handler, mediaUrl, args.Url.QueryString, true);
                                args.AbortPipeline();
                            }
                            Context.Page.FilePath = mediaUrl;
                        }
                    }
                }
                Profiler.EndOperation();
            }
        }


        private static bool IsMediaItem(Item item)
        {
            Assert.ArgumentNotNull(item, "item");
            return item.Paths.IsMediaItem && item.TemplateID != TemplateIDs.MediaFolder;
        }

        private static string GetAbsoluteMediaUrl(MediaItem mediaItem)
        {
            string relativeUrl = MediaManager.GetMediaUrl(mediaItem);
            return WebUtil.GetFullUrl(relativeUrl);
        }


        private bool ProcessExternalUrl(HttpRequestArgs args)
        {
            string targetUrl = Context.Database.Aliases.GetTargetUrl(args.LocalPath);
            if (targetUrl.Length > 0)
                return this.ProcessExternalUrl(targetUrl);
            return false;
        }


        private bool ProcessExternalUrl(string path)
        {
            if (Context.Page.FilePath.Length > 0)
                return false;
            Context.Page.FilePath = path;
            return true;
        }


        private bool ProcessItem(HttpRequestArgs args)
        {
            var item = Sitecore.Context.Database.GetItem(args.Url.ItemPath);
            if (item != null && item.TemplateID == Templates.MediaReference.ID)
            {
                if (!string.IsNullOrEmpty(item[Templates.MediaReference.Fields.ContentReference]))
                {
                    ID targetId = new ID(item[Templates.MediaReference.Fields.ContentReference]);
                    if (!targetId.IsNull)
                    {
                        Item target = args.GetItem(targetId);
                        if (target != null)
                            this.ProcessItem(args, target);
                        return true;
                    }
                }

            }
            Tracer.Error((object)("An alias for \"" + args.LocalPath + "\" exists, but points to a non-existing item."));
            return false;
        }

       
        private void ProcessItem(HttpRequestArgs args, Item target)
        {
            if (Context.Item != null)
                return;
            Context.Item = target;
            Tracer.Info((object)("Using alias for \"" + args.LocalPath + "\" which points to \"" + (object)target.ID + "\""));
        }

After that I created a .config file and added below pipeline code into that config file. In below code added new processor to handle the custom Alias Resolver requests. And I added it just before  “AliasResolver” processor.

<sitecore>
  <pipelines>
    <httpRequestBegin>
        <processor patch:before="processor[@type='Sitecore.Pipelines.HttpRequest.AliasResolver, Sitecore.Kernel']" type="SitecoreDemo.Feature.MediaReference.CustomAliasResolver.CustomAliasResolver, SitecoreDemo.Feature.MediaReference"/>
    </httpRequestBegin>
   </pipelines>
 </sitecore>

After the above configuration and code I was able to render Media Item over the Sitecore Item. This code was for media item but we can achieve multiple similar types of requirement with the same approach.

Advertisements
This entry was posted in Sitecore and tagged , , . Bookmark the permalink.

Leave a Reply

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 )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s