Enhancing the dictionary in older versions of Sitecore

The projects I’m working on at the moment are largely stuck using older versions of Sitecore. Whilst our friends at Sitecore UK would love us to upgrade to new versions as soon as they appear, for some of my clients that is not practical for a variety of reasons. However some of the features in newer releases of Sitecore would still be useful in these projects – so recently I found myself quickly coding up a simple version of something like the dictionary domains functionality in SC6.6.

The behaviour I needed to enable was to be able to have separate dictionaries for different aspects of the site – to be able to move dictionary entries away from their standard location in /sitecore/System/Dictionary. You can do this by providing a custom “translate” method that your code can call to turn a dictionary item path into some text.

The basic code required is a static method that can take a dictionary item location and return the translated string. While you can pass the item’s path as a single string, for the purposes of the work I was doing, splitting the item name and its path into separate parameters made sense. (I’m not going to go into all of that here – You might prefer to have this as a single string) Also, it makes sense to have a short-cut for “translate this to the current language” as well as “translate this to a specific language”:

public static class Dictionary
{
    public static string Translate(string folder, string key)
    {
        return Translate(folder, key, Sitecore.Context.Language);
    }
    public static string Translate(string folder, string key, Language language)
    {
        // do the translation here
    }
}

So you could call this as Dictionary.Translate("/sitecore/Content/Home/Dictionary", "TitleLable") as long as you had a content tree containing the appropriate items:

image

Note that by default the insert options in your content tree won’t include the Dictionary Folder or Dictionary Entry templates – so you’ll either need to add them yourself, or use Insert From Template and then find the appropriate template under the path Templates/Dictionary in the picker dialog.

So what code is needed to make this work? Actually very little:

There are a few ways we could find the appropriate items, but the simplest is just to use the Item APIs to load the Dictionary Entry. We have to remember to load it in the appropriate language, handle the “not found” situation and handle the “doesn’t exist in this language” situation:

public static string Translate(string folder, string key, Language language)
{
    // work out the full path to the dictionary item
    string folderPath = string.Format("{0}/{1}", folder, key);
    
    // try to load the item
    Item item = Sitecore.Context.Database.GetItem(folderPath, language);
    
    // If we didn't find an item, then stop
    if (item == null)
    {
        return key;
    }
    
    // If the item doesn't exist in the required language, then stop
    if (item.Versions.Count <= 0)
    {
        return key;
    }
    
    // Return the translated text
    return item.Fields["Phrase"].Value;
}

So this code will perform a translation for us – but it only works from the code-behind of your class. It’s also useful to be able to use translations from within your ASPX files. And a simple literal control can do that for us:

public class DictionaryLiteral : System.Web.UI.Control
{
    private string _text = string.Empty;

    public string DictionaryFolder { get; set; }
    public string DictionaryKey { get; set; }

    private string error(string message)
    {
        return string.Format("<span style="font-weight:bold;color:red;">{0}</span>", message);
    }

    protected override void OnPreRender(EventArgs e)
    {
        if (string.IsNullOrWhiteSpace(DictionaryFolder))
        {
            _text = error("Missing folder for dictionary literal");
            return;
        }

        if (string.IsNullOrWhiteSpace(DictionaryKey))
        {
            _text = error("Missing key for dictionary literal");
            return;
        }

        _text = Dictionary.Translate(DictionaryFolder, DictionaryKey);
    }

    protected override void Render(System.Web.UI.HtmlTextWriter writer)
    {
        writer.Write(_text);
    }
}

This takes the dictionary folder and key we would have passed to our original class as properties of an ASPX tag, and then uses that to run the translation. This only works with the context language. You could use this as follows:

 
<%@ Register TagPrefix="c" Namespace="YourNamespace" Assembly="YourAssembly" %>
<h2>Dictionary Test</h2>
<c:DictionaryLiteral runat="server" DictionaryFolder="/sitecore/Content/Home/Dictionary" DictionaryKey="TitleLable" />

And that will inject the translation into the page…

Advertisements

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