Wednesday, February 24, 2010

Insert Media Item dialog in rich text field – remember last selection


Just last week I was at a customer talking to end users, authors who use the Sitecore CMS every day. It was was a very productive session, some quite valuable feedback was gathered.

One of the reported inconveniences with the rich text editor was inability for the “Insert Media Item” dialog to remember the previously selected location. It always falls back to the media library root when opened.
Insert Media Item - new

With active  content entry, especially media related, this dialog is used quite often.
Plus as the media library grows significantly, it takes more time to browse through the media library structure to locate the much needed media.

Thanks to Sitecore’s customizability, you can easily change that. By simply overriding the InsertImage XML control with new code that remembers the previous location.

namespace SCUSAINC.Shell.Applications.Dialogs
{
   using System;
   using Sitecore;
   using Sitecore.IO;
   using Sitecore.Data.Items;
   using Sitecore.Data;
   using Sitecore.Resources.Media;
   using Sitecore.Diagnostics;

   class InsertImageForm : Sitecore.Shell.Controls.RichTextEditor.InsertImage.InsertImageForm
   {
      protected override void OnLoad(EventArgs e)
      {
         Assert.ArgumentNotNull(e, "e");
         if (!Context.ClientPage.IsEvent)
         {
            var prevMedia = Context.ClientPage.Session["prevMedia"];
            DataContext.GetFromQueryString();
            Item folder;
            if (prevMedia != null)
            {
               folder = Context.ContentDatabase.GetItem(ID.Parse(prevMedia.ToString()));
               if (folder != null)
               {
                  DataContext.SetFolder(folder.Uri);
               }
            }
         }
         base.OnLoad(e);
      }

      protected override void OnOK(object sender, EventArgs args)
      {
         base.OnOK(sender, args);

         var filename = Filename.Value;
         if (filename.Length != 0)
         {
            var root = DataContext.GetRoot();
            if ((root != null) && (root.ID != root.Database.GetRootItem().ID))
            {
               filename = FileUtil.MakePath(root.Paths.Path, filename, '/');
            }
            MediaItem item = DataContext.GetItem(filename);
            if ((item != null) && ((MediaManager.GetMedia(MediaUri.Parse(item)) is ImageMedia)))
            {
               Context.ClientPage.Session.Add("prevMedia", item.ID.ToString());
            }
         }
      }
   }
}

After the code is compiled, you will need to copy the source file of the InsertImage XML control that can be found here: \sitecore\shell\Controls\Rich Text Editor\InsertImage\ to the \sitecore\shell\Override\ folder and make the following change:

<CodeBeside Type="SCUSAINC.Shell.Applications.Dialogs.InsertImageForm,SCUSAINC"/>

Huge thanks goes to Kirill T from the customer service for the solution!

Related reading:
http://sdn.sitecore.net/Scrapbook/Customize%20an%20XML%20Control.aspx

Enjoy and please do share if you like it! ;-)

1 comments:

Blogging from SF said...

Hi Alex -- As always, you prove that you are a genius. I tried this code and had to make one tweak for Sitecore 6.4 and higher (may affect earlier versions as well).

It looks like the ClientPage.Session object is no longer supported, so I used Registry.GetValue/SetValue to manage the last-accessed media item, per your suggestion.

Thanks!
Derek