Earlier today when doing research for another blog post around on-demand language translation in Sitecore, I remembered I wanted to blog about an issue I saw a while back when using the Sitecore Dictionary, but before I dive into that issue — and a possible approach for resolving it — let me give you a little information on what the Sitecore Dictionary is, and why you might want to use it — actually you probably should use it!
The Sitecore Dictionary is a place in Sitecore where you can store multilingual content for labels or string literals in your code (this could be front-end code, or even content displayed in the Sitecore shell). I’ve created the following Dictionary entry as an example:
The “coffee” item above is the Dictionary entry, and its parent item “beverage types” is a Dictionary folder.
You could use a sublayout like the following to display the text stored in the Phrase field on the front-end of your website:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Translate Test.ascx.cs" Inherits="Sandbox.layouts.sublayouts.Translate_Test" %> <h2>Dictionary Test</h2> Key => <asp:Literal ID="litKey" runat="server" /><br /> Phrase => <asp:Literal ID="litTranslateTest" runat="server" />
The code-behind of the sublayout:
using System; using Sitecore.Globalization; namespace Sandbox.layouts.sublayouts { public partial class Translate_Test : System.Web.UI.UserControl { protected void Page_Load(object sender, EventArgs e) { string key = "beveragetypes.coffee"; litKey.Text = key; litTranslateTest.Text = Translate.Text(key); } } }
In the Page_Load method above, I’ve invoked Sitecore.Globalization.Translate.Text() to grab the value out of the Phrase field of the “coffee” Dictionary entry using its key. The Sitecore.Globalization.Translate.Text() method uses Sitecore.Context.Language to ascertain which language version of the Dictionary entry to use.
When I navigated to the page that has the sublayout above mapped to its presentation, I see the “coffee” entry’s Phrase appear:
Let’s see how this works using another language version of this Dictionary entry. I added a Danish version for our “coffee” entry:
I navigated to my page again after embedding the Danish language code in its URL to get the Danish version of this Dictionary entry:
As you can see the Danish version appeared, and I did not have to write any additional code to make this happen.
Well, this is great and all until someone forgets to include a phrase for a Dictionary entry:
When we go to the front-end, we see that the Dictionary entry’s key appears instead of its phrase:
As a fix for this, I created the following class to serve as a processor for the <getTranslation> pipeline (this pipeline was introduced in Sitecore 6.6):
using System.Collections.Generic; using Sitecore.Diagnostics; using Sitecore.Pipelines.GetTranslation; namespace Sitecore.Sandbox.Pipelines.GetTranslation { public class SetAsEmpty { private IList<string> _KeyPrefixes; private IList<string> KeyPrefixes { get { if (_KeyPrefixes == null) { _KeyPrefixes = new List<string>(); } return _KeyPrefixes; } } public void Process(GetTranslationArgs args) { if (!ShouldSetAsEmpty(args)) { return; } args.Result = string.Empty; } protected virtual bool ShouldSetAsEmpty(GetTranslationArgs args) { Assert.ArgumentNotNull(args, "args"); return args.Result == null && HasKeyPrefix(args.Key); } protected virtual bool HasKeyPrefix(string key) { if (string.IsNullOrWhiteSpace(key)) { return false; } foreach (string keyPrefix in KeyPrefixes) { if (key.StartsWith(keyPrefix)) { return true; } } return false; } protected virtual void AddKeyPrefix(string keyPrefix) { if(string.IsNullOrWhiteSpace(keyPrefix)) { return; } KeyPrefixes.Add(keyPrefix); } } }
The idea here is to check to see if the Dictionary entry’s key starts with a configuration defined prefix, and if it does, set the GetTranslationArgs instance’s Result property to the empty string when it’s null.
The reason why we check for a specific prefix is to ensure we don’t impact other parts of Sitecore that use methods that leverage the <getTranslation> pipeline (I learned this the hard way when virtually all labels in my instance’s Content Editor disappeared before adding the logic above to check whether a Dictionary entry’s key started with a config defined prefix).
I then wired this up in Sitecore using the following configuration file:
<?xml version="1.0" encoding="utf-8"?> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"> <sitecore> <pipelines> <getTranslation> <processor type="Sitecore.Sandbox.Pipelines.GetTranslation.SetAsEmpty, Sitecore.Sandbox"> <keyPrefixes hint="list:AddKeyPrefix"> <prefix>beveragetypes.</prefix> </keyPrefixes> </processor> </getTranslation> </pipelines> </sitecore> </configuration>
When I navigated back to my page, I see that nothing appears for the Dictionary entry’s phrase since it was set to the empty string by our pipeline processor above.
One thing I should note: I have only tested this in Sitecore 6.6, and I’m not aware if this Dictionary entry issue exists in Sitecore 7. If this issue was fixed in Sitecore 7, please share in a comment.
Plus, if you have any comments on this, or other ideas for solving this problem, please leave a comment.