Tuesday, May 12, 2015

Localize Property Name Based on Content Language

We recently had a client request that a page property have a different display name for each language branch.  The function of the property was as an identifier and would always be used the same in the back end but the editors in each country had a different name for the property.

This isn't a particularly inspired solution, but I'm hoping to save someone else the time it took to stumble upon this.

It is possible to localize EPi property names using the built in Display attribute and keeping the translations in resources files (see this stackoverflow post here), but this is only based on the UI language in Edit/Admin mode and not on content language.

I created an EditorDescriptor that will take the string entered in the Name field and try to translate it using the registered LocalizationService (whatever that may be).  An important thing to note is the EditorDescriptorBehavior.  We have to have it as EditorDescriptorBehavior.PlaceLast to ensure that any other logic to get the Display Name (built in translation, etc) does not interfere with what we want displayed.

Code


[EditorDescriptorRegistration(TargetType = typeof(String), UIHint = SiteUIHints.LocalizedDisplay, EditorDescriptorBehavior = EditorDescriptorBehavior.PlaceLast)]
public class LocalizableDisplayEditorDescriptor : EditorDescriptor
{
   public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
   {
      base.ModifyMetadata(metadata, attributes);

      Attribute attr = attributes.FirstOrDefault(a => a.GetType() == typeof(DisplayAttribute));
      if (attr != null)
      {
         string translated =                                     

             ServiceLocator.Current.GetInstance<LocalizationService().GetStringByCulture(metadata.DisplayName, 
             FallbackBehaviors.None, ContentLanguage.PreferredCulture);

         if (!string.IsNullOrWhiteSpace(translated))
            metadata.DisplayName = translated;
      }
   }
}



Usage

[UIHint(SiteUIHints.LocalizedDisplay)]
[Display(Name = "/properties/InternalId/displayname", Order = 200)]
public virtual string InternalId { get; set; }