Subscribe:

Pages

Saturday, February 25, 2012

Sitecore Item Renamed Event Handler

This post is continuation of my previous post Sitecore Custom Token for Display Name which describes how to create a custom token for SEO friendly item name. As described in my previous post we need to handle a case where item is renamed, to update the display name of item to new item name.

So in this post I am going to create a custom event handler for Sitecore item renamed event. Goal of this custom event handler is to check if any of the fields in Sitecore item are using “$displayname” token and replace the “$displayname” token with new item name.

First let’s create a class file for our event handler and name it “ItemEventHandler.cs” which looks as follows

public class ItemEventHandler
    {
        public void OnItemRenamed(object sender, EventArgs args)
        {
            Item itm = Event.ExtractParameter(args, 0) as Item;
            itm.Fields.ReadAll();
            using (new Sitecore.SecurityModel.SecurityDisabler())
            {
                itm.Editing.BeginEdit();
                //Get all the fields which has $displayname token standard value
                foreach (Field fld in itm.Fields.Where(x => x.GetStandardValue() != null && x.GetStandardValue().Equals("$displayname")))
                {
                    //check if user has changed the standard value
                    if ((Event.ExtractParameter(args, 1) as string).ToTitleCase().Equals(itm.Fields[fld.ID].Value))
                    {
                        itm.Fields[fld.ID].Value = itm.Name.ToTitleCase();
                    }
                }
                itm.Editing.EndEdit();
            }
        }
    }

You may note that I am not replacing the token if filed value has been modified by the user.

Now we need to register our custom event handler, to do this go to custom.config file we created as described in previous post and add following under Sitecore node.

<events>
  <event name="item:renamed">
    <handler type="Namespace.ItemEventHandler, assembly name" method="OnItemRenamed"/>
  </event>
</events>

Feel free to post your comments or suggestions.

Saturday, February 18, 2012

Sitecore Custom Token for Display Name

I've been thinking of blogging my Sitecore work from a long time, but as usual starting trouble (lazy). Finally today I am composing my first Sitecore blog. I know you don’t like all this nonsense so coming to the point directly.

We all know that Sitecore uses item name for URL and it’s also very important today to build our websites with SEO friendly URL's to improve visibility of website over internet. At the same time content authors would like to see the friendly item names in content tree like PascalCase or UpperCamelCase with spaces not the hyphens. And they might need to edit content when we use $name token. For SEO friendly URL’s we need URL to be in lower case and no spaces or special characters.

To resolve this Sitecore has provided us Display Name field in Appearance section of Standard Template. Oops one more extra field to be filled! Doesn’t worry we can use standard values to auto populate it. But unfortunately we don't have an out-of-box token to do it. Again the reason I love sitecore so much is it can be easily customized or extended. So I decided to create my own token "$displayname" which would replace hyphens in item name with space and convert text to PascalCase.

Before we start our token code we need a method to convert the text to PascalCase and replace hyphens with space. Fortunately I discovered System.Globalization.TextInfo class has a method "ToTitleCase" which would do this. So I have created class with string extension method as follows

public static class StringExtensions
{
    /// <summary>
    /// Use the current thread's culture info for conversion
    /// </summary>
    public static string ToTitleCase(this string str)
    {
        var cultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture;
        return cultureInfo.TextInfo.ToTitleCase(str.ToLower());
    }
}

Then I created class for my custom token as follows

public class DisplayNameToken : ExpandInitialFieldValueProcessor
{
    public override void Process(ExpandInitialFieldValueArgs args)
    {
        if (args.SourceField.Value.Contains("$displayname"))
        {
            args.Result = args.TargetItem.Name.ToTitleCase();
        }
    }
}

Then we need to register our custom token, to do this create custom.config file under App_config/Include folder and add processor to ExpandInitialFieldValue under pipelines.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <pipelines>
      <expandInitialFieldValue>       
        <processor type="Namespace.DisplayNameToken, assembly name" />
      </expandInitialFieldValue>
    </pipelines>
  </sitecore>
</configuration>

Now we can use "$displayname" custom token in our standard values to display a friendly name in content tree.
It’s not over yet, just think what happens if user renames item, he would still see old name in content tree. To solve this I have created a custom event handler for item renamed event as described in my post Sitecore Item Renamed Event Handler.

So we are done now? No, if you check standard values node for template in template manager it now displays "$displayname" instead of "__standardValues". I think may be sitecore should fix this, I feel "__standardValues" should not use displayname at least when there is a token in it. Huff what's next.... I would say as templates will be mostly created by us (developers) we can ignore it. If you don't agree I have one option you can go to sitecore control panel > preferences > change your application options > view then select itemkey option in item names section. You can as well do it from content editor by clicking on circular logo on top left and then application settings. Off course you would now see the normal item names with hyphen ha ha we need displayname for content authors.

Also you should force authors to use small letters and hyphens by changing ItemNameValidation key in web.config of content authoring environment to "^[a-z0-9][a-z0-9\-]*[a-z0-9\-]+(\(\d{1,}\)){0,1}$" ,I am allowing a digit like "(1)" at the end you can restrict if you need. Also note that we should do it in only authoring environment not developing environment as sitecore uses '_','$' and space etc. when creating items like __standard values and branches etc.

I will discuss few more points in my next post.

Feel free to post your comments and suggestions.