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! ;-)

Friday, February 05, 2010

Sitecore 6 quick tip. Email as user name for authentication


It is pretty common to have email served as username for authentication in web systems for both visitors and internal users. Sitecore Content Management System is no exception.

With 5.3 it was pretty easy since users were just items – adjust the regex of the “ItemNameValidation” setting, make sure you don’t have @ and dots in the “InvalidItemNameChars” setting and you are pretty much set.

Now as you know, Sitecore 6 has different rules for security so you will need to do the following to make it work:
1. Make sure the membership provider treats email as a unique attribute for users so you don’t end up with more than one user attached to the same email:
<add name="sql" type="System.Web.Security.SqlMembershipProvider" connectionStringName="core" applicationName="sitecore" minRequiredPasswordLength="1" minRequiredNonalphanumericCharacters="0" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" maxInvalidPasswordAttempts="256" />

2. Put email into both username and email properties (fields) of a user during the registration (can be handled via code).

3. Introduce the following entry into the web.config’s <settings> section. The “value” attribute parameter contains the regular expression used in the Create User dialog within User Manager. This regex should allow emails, otherwise Sitecore will fallback on a default regex that does not allow it.
<setting name="AccountNameValidation" value=".+" />

4. If you want to handle the case when email needs to be changed, either provide an extranet form for the profile section on your website or you can even take it one step forward – modify the EditUser dialog within User Manager to have this ability.

Happy coding!