Navigation and service panel


Content

This text is fallbacked from the German Version. If you need use Google Translate


DataAnnotation-Attribute in Sitecore übersetzen

By Tobias Studer on 29. August 2013, No comments

DataAnnotation-Attribute sind ein praktisches Werkzeug, um bei Formularen Labels oder Validierungsnachrichten zentral auf einem ViewModel zu verwalten. Bauen wir mehrsprachige Webseiten, so wollen wir auch die Texte in den gewünschten Sprachen ausgeben. Dieser Beitrag zeigt eine Möglichkeit, die Übersetzungen in Sitecore zu erfassen.

Als Beispiel dient ein sehr einfaches Kontaktformular. Dieses besteht nur aus einem Feld für die Nachricht und einem Submit-Button. Für das in Sitecore MVC umgesetzte Formular definieren wir als erstes das ViewModel:

public class ContactViewModel
{
     public string Message { get; set; }
}

In der View wird ein Formular definiert, für welches wir ein Label, eine mehrzeilige Textbox und später eine Validierungsnachricht ausgeben. Diese könnte folgendermassen aussehen:

@model ContactViewModel

using (Html.BeginForm())
{
        @Html.LabelFor(model => model.Message)
        @Html.TextAreaFor(model => model.Message)
        @Html.ValidationMessageFor(model => model.Message)
        
        <input type="submit" value="Send" />
        
}

Label übersetzen

Um die Ausgabe der LabelFor-Helper Methode zu steuern, können wir das DisplayName-Attribut verwenden. Für eine Mehrsprachigkeit können wir Resource-Files einsetzen. Wir können aber auch das Attribut erweitern und das Label in Sitecore übersetzen. Dazu erstellen wir ein neues Attribut, und vererben das DisplayName-Attribut. Es reicht danach, das DisplayName-Property zu überschreiben und darin auf das gewünschte Sitecore-Item zuzugreifen, welches den übersetzten Text beinhaltet.

public class SitecoreDisplayNameAttribute : DisplayNameAttribute
{

        private readonly string path;

        public SitecoreDisplayNameAttribute(string path)
        {
            this.path = path;
        }

        public override string DisplayName
        {
            get
            {
                return SitecoreMagic.GetTranslationFromItem(this.path);
            }
        }
    }

Danach erweitert man das ViewModel mit dem neuen Attribute und hat nun die Möglichkeit, die Sitecore-Funktionalität für Mehrsprachigkeit zu verwenden.

public class ContactViewModel

{

        [SitecoreDisplayName("path/to/sitecore/item")]
        public string Message { get; set; }
}

Validierung übersetzen

Spannender wird es bei Validierungen. Das .NET Framework bringt von Haus aus zwei Möglichkeiten mit, Validationsnachrichten mehrsprachig anzubieten. Die einfachste Variante dabei ist, das gewünschte Language Pack des .NET Frameworks zu installieren und sicherzustellen, dass die Culture und die UICulture auf dem aktuellen Thread entsprechend gesetzt sind. Dabei ist man soweit eingeschränkt, dass es nicht für jede beliebige Sprache ein Language Pack gibt. Auch kann man die Nachrichten nicht beeinflussen. Will man diese Einschränkungen umgehen stehen einem wiederum Resource-Files zur Verfügung.

Doch auch hier können wir die gewünschten Texte in Sitecore pflegen. Zuerst definieren wir das Message-Property als Required:


public class ContactViewModel

{

        [Required]
        [SitecoreDisplayName("path/to/sitecore/item")]
        public string Message { get; set; }
}

Danach schreiben wir einen eigenen Adapter für das Attribut, welcher für die Textausgabe zuständig ist. Dazu erben wir in diesem Fall vom RequiredAttributeAdapter:

public class SitecoreRequiredAttributeAdapter : RequiredAttributeAdapter
{...}

Hier müssen wir die GetClientValidationRules-Methode überschreiben:

public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{

        var name = this.Attribute.GetType().Name;

        var errorMessage = string.Empty;
        var genericMessageWithPlaceHolder = SitecoreMagic.GetValidationPlaceholderFromItem("path/to/sitecore/validation/" + name);
    
        if (!string.IsNullOrWhiteSpace(genericMessageWithPlaceHolder))
        {
            errorMessage = string.Format(genericMessageWithPlaceHolder, Metadata.GetDisplayName());
        }

        return new[] { new ModelClientValidationRequiredRule(errorMessage) };
}

Der von Sitecore zurück gegebene Text sollte die erwarteten Placeholder enthalten, also zum Beispiel:

<pre class="brush:xml;" xml:space="preserve">The {0} field is required.

Damit haben wir die Validierungsausgabe verändert. Als letzten Schritt müssen wir noch den neuen Adapter für das Attribut registrieren. Dies sollte beim Applikationsstart geschehen, z.B. mit dem AppActivator:

[assembly: WebActivator.PreApplicationStartMethod(typeof(Example.AppActivator), "PreStart")]
namespace Example
{
    using System.ComponentModel.DataAnnotations;
    using System.Web.Mvc;

    public static class AppActivator
    {
        public static void PreStart()
        {
            DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredAttribute), typeof(SitecoreRequiredAttributeAdapter));
        }
    }
}

Verschiedene Validierungsnachrichten für ein Attribut

Mit dieser Umsetzung ist es möglich, pro Validierungsattribut genau einen Text zu definieren. Ein kleiner Trick ermöglicht es jedoch, mehrere Texte pro Validierungsattribut zu verwenden. Dazu zweckentfremden wir die ErrorMessage, welche dem Attribute mitgegeben werden kann als Identifizierung des gewünschten Items:

public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{

        var name = this.Attribute.ErrorMessage;
        if (string.IsNullOrWhiteSpace(name))
        {
            name = this.Attribute.GetType().Name;
        }

        var errorMessage = string.Empty;
        var genericMessageWithPlaceHolder = SitecoreMagic.GetValidationPlaceholderFromItem("path/to/sitecore/validation/" + name);
        if (!string.IsNullOrWhiteSpace(genericMessageWithPlaceHolder))
        {
        errorMessage = string.Format(genericMessageWithPlaceHolder, Metadata.GetDisplayName());
        }

        return new[] { new ModelClientValidationRequiredRule(errorMessage) };
}

Nun haben wir die Möglichkeit, das gewünschte Übersetzungs-Item zu verändern:

public class ContactViewModel

{
        [Required(ErrorMessage = "CustomRequired")]
        [SitecoreDisplayName("path/to/sitecore/item")]
        public string Message { get; set; }
}

Mit eigenen Adaptern können wir so die gewünschten Validierungsattribute übersetzen, mit Sitecore oder einer beliebigen anderen Übersetzungsquelle. Auch die clientseitige Validierung, die in der web.config aktiviert werden kann, funktioniert mit diesem Konstrukt.

No comments

Add your comment

Your email address will not be published. Required fields are marked *

*