it-swarm.com.de

Lokalisieren Sie Strings in Javascript

Derzeit verwende ich .resx-Dateien, um meine serverseitigen Ressourcen für .NET zu verwalten.

die Anwendung, mit der ich mich befasse, ermöglicht es Entwicklern außerdem, JavaScript in verschiedene Event-Handler für die Validierung auf Clientseite usw. einzufügen. Wie kann ich meine JavaScript-Meldungen und -Strings am besten lokalisieren? 

Im Idealfall möchte ich die Zeichenfolgen in den .resx-Dateien speichern, um sie bei den restlichen lokalisierten Ressourcen zu behalten.

Ich bin offen für Vorschläge.

38
SaaS Developer

Ein grundlegendes JavaScript-Objekt ist ein assoziatives Array und kann daher problemlos zum Speichern von Schlüssel/Wert-Paaren verwendet werden. Wenn Sie also JSON verwenden, können Sie für jeden zu lokalisierenden String ein Objekt wie folgt erstellen:

var localizedStrings={
    confirmMessage:{
        'en/US':'Are you sure?',
        'fr/FR':'Est-ce que vous êtes certain?',
        ...
    },

    ...
}

Dann könnten Sie die Gebietsschema-Version jeder Zeichenfolge wie folgt erhalten:

var locale='en/US';
var confirm=localizedStrings['confirmMessage'][locale];
25
Joel Anair

Inspiriert von SproutCore Sie können Eigenschaften von Zeichenfolgen festlegen:

'Hello'.fr = 'Bonjour';
'Hello'.es = 'Hola';

und dann einfach die richtige Lokalisierung basierend auf Ihrem Gebietsschema ausspucken:

var locale = 'en';
alert( message[locale] );
13
Ryan

Nachdem ich viel gegoogelt hatte und mit der Mehrzahl der vorgestellten Lösungen nicht zufrieden war, habe ich gerade eine erstaunliche/generische Lösung gefunden, die T4-Vorlagen verwendet. Den vollständigen Beitrag von Jochen van Wylick können Sie hier lesen:

T4 zum Lokalisieren von JavaScript-Ressourcen basierend auf .resx-Dateien verwenden

Hauptvorteile sind:

  1. Nur eine Stelle haben, an der Ressourcen verwaltet werden (nämlich die .resx -Dateien)
  2. Unterstützung für mehrere Kulturen
  3. Nutzen Sie IntelliSense - Ermöglichen Sie die Code-Vervollständigung

Nachteile:

Die Nachteile dieser Lösung sind natürlich die Größe der Die .js-Datei wird möglicherweise ziemlich groß. Da es jedoch von der .__ zwischengespeichert wird. Browser betrachten wir dies nicht als Problem für unsere Anwendung. Jedoch - Diese Zwischenspeicherung kann auch dazu führen, dass der Browser die vom Code aufgerufene Ressource nicht findet.


Wie funktioniert das?

Grundsätzlich hat er eine T4-Vorlage definiert, die auf Ihre RESX-Dateien verweist. Mit etwas C # -Code durchläuft er jeden Ressourcenstring und fügt ihn den reinen JavaScript-Schlüsselwerteigenschaften hinzu, die dann in einer einzigen JavaScript-Datei mit dem Namen Resources.js ausgegeben werden (Sie können die Namen nach Bedarf anpassen).


T4-Vorlage [entsprechend ändern, um auf den Speicherort der RESX-Dateien zu verweisen]

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ Assembly name="System.Windows.Forms" #>
<#@ import namespace="System.Resources" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.IO" #>
<#@ output extension=".js"#>
<#
 var path = Path.GetDirectoryName(Host.TemplateFile) + "/../App_GlobalResources/";
 var resourceNames = new string[1]
 {
  "Common"
 };

#>
/**
* Resources
* ---------
* This file is auto-generated by a tool
* 2012 Jochen van Wylick
**/
var Resources = {
 <# foreach (var name in resourceNames) { #>
 <#=name #>: {},
 <# } #>
};
<# foreach (var name in resourceNames) {
 var nlFile = Host.ResolvePath(path + name + ".nl.resx" );
 var enFile = Host.ResolvePath(path + name + ".resx" );
 ResXResourceSet nlResxSet = new ResXResourceSet(nlFile);
 ResXResourceSet enResxSet = new ResXResourceSet(enFile);
#>

<# foreach (DictionaryEntry item in nlResxSet) { #>
Resources.<#=name#>.<#=item.Key.ToString()#> = {
 'nl-NL': '<#= ("" + item.Value).Replace("\r\n", string.Empty).Replace("'","\\'")#>',
 'en-GB': '<#= ("" + enResxSet.GetString(item.Key.ToString())).Replace("\r\n", string.Empty).Replace("'","\\'")#>'
 };
<# } #>
<# } #>

In der Formular-/Ansichtsseite

Um die richtige Übersetzung zu erhalten, fügen Sie dies in Ihrem Master ein, wenn Sie WebForms verwenden:

<script type="text/javascript">

    var locale = '<%= System.Threading.Thread.CurrentThread.CurrentCulture.Name %>';

</script>

<script type="text/javascript" src="/Scripts/Resources.js"></script>

Wenn Sie ASP.NET MVC (wie ich) verwenden, können Sie Folgendes tun:

<script type="text/javascript">

    // Setting Locale that will be used by JavaScript translations
    var locale = $("meta[name='accept-language']").attr("content");

</script>

<script type="text/javascript" src="/Scripts/Resources.js"></script>

Der MetaAcceptLanguage-Helfer, den ich von diesem tollen Beitrag von Scott Hanselman bekam:

Globalisierung, Internationalisierung und Lokalisierung in ASP.NET MVC 3, JavaScript und jQuery - Teil 1

public static IHtmlString MetaAcceptLanguage<T>(this HtmlHelper<T> html)
{
     var acceptLanguage =
         HttpUtility.HtmlAttributeEncode(
                     Thread.CurrentThread.CurrentUICulture.ToString());

      return new HtmlString(
      String.Format("<meta name=\"{0}\" content=\"{1}\">", "accept-language",
                    acceptLanguage));
 }

Benutze es

var msg = Resources.Common.Greeting[locale];
alert(msg);
10

JSGettext leistet einen hervorragenden Job - dynamisches Laden von GNU Gettext .po-Dateien in nahezu jeder Sprache des Backends. Google für "Dynamische Javascript-Lokalisierung mit Gettext und PHP", um einen Lösungsweg für JSGettext mit PHP zu finden (ich würde den Link posten, aber diese alberne Seite lässt mich nicht seufzen ...)

Edit: das sollte der Link sein

4
Jani Patokallio

Ich würde eine Objekt-/Array-Notation verwenden:

var phrases={};
phrases['fatalError'] ='On no!';

Dann können Sie einfach die JS-Datei austauschen oder einen Ajax-Aufruf verwenden, um Ihre Phrasenliste neu zu definieren.

Mit einer Satellitenassembly (anstelle einer ResX-Datei) können Sie alle Zeichenfolgen auf dem Server auflisten, von denen Sie die Sprache kennen, und ein Javascript-Objekt nur mit den Zeichenfolgen für die richtige Sprache erstellen. 

So etwas funktioniert für uns (VB.NET-Code):

Dim rm As New ResourceManager([resource name], [your Assembly])
Dim rs As ResourceSet = 
    rm.GetResourceSet(Thread.CurrentThread.CurrentCulture, True, True)
For Each kvp As DictionaryEntry In rs
    [Write out kvp.Key and kvp.Value]
Next

Leider haben wir noch keinen Weg gefunden, dies für .resx-Dateien zu tun.

4
Erik Hesselink

Es gibt eine Bibliothek zum Lokalisieren von JavaScript-Anwendungen: https://github.com/wikimedia/jquery.i18n

Es kann Parameter ersetzen, unterstützt Geschlecht (geschickte Handhabung), Anzahl (geschickte Pluralbehandlung, einschließlich Sprachen, die mehr als eine Pluralform haben) und benutzerdefinierte Grammatikregeln, die einige Sprachen benötigen.

Die Zeichenfolgen werden in JSON-Dateien gespeichert.

Die einzige Voraussetzung ist jQuery.

3
Amir E. Aharoni

Ich habe Folgendes getan, um JavaScript für eine mobile App mit HTML5 zu lokalisieren:

1.Erstellen Sie eine Reihe von Ressourcendateien für jede Sprache, die sie wie "en.js" für Englisch nennt. Jede enthielt die verschiedenen Strings der App wie folgt:


        var localString = {
        appName: "your app name",
        message1: "blah blah"
      };

2.Benutzte Lazyload, um die richtige Ressourcendatei basierend auf der Landessprache der App zu laden: https://github.com/rgrove/lazyload

3.Pass den Sprachcode über eine Abfragezeichenfolge (Da ich die html-Datei von Android mit PhoneGap starte)

4. Dann habe ich folgenden Code geschrieben, um die richtige Ressourcendatei dynamisch zu laden:


var lang = getQueryString("language");
localization(lang);
function localization(languageCode) {
    try {
        var defaultLang = "en";
        var resourcesFolder = "values/";
        if(!languageCode || languageCode.length == 0)
            languageCode = defaultLang;
        // var LOCALIZATION = null;
        LazyLoad.js(resourcesFolder + languageCode + ".js", function() {
            if( typeof LOCALIZATION == 'undefined') {
                LazyLoad.js(resourcesFolder + defaultLang + ".js", function() {
                    for(var propertyName in LOCALIZATION) {
                        $("#" + propertyName).html(LOCALIZATION[propertyName]);
                    }
                });
            } else {
                for(var propertyName in LOCALIZATION) {
                    $("#" + propertyName).html(LOCALIZATION[propertyName]);
                }
            }
        });
    } catch (e) {
        errorEvent(e);
    }
}
function getQueryString(name)
{
  name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
  var regexS = "[\\?&]" + name + "=([^&#]*)";
  var regex = new RegExp(regexS);
  var results = regex.exec(window.location.href);
  if(results == null)
    return "";
  else
    return decodeURIComponent(results[1].replace(/\+/g, " "));
}

5.Von der HTML-Datei verweise ich auf die Zeichenfolgen wie folgt:


    span id="appName"
2
Jaime Botero

Nun, ich denke, das kann man bedenken. Englisch-Spanisch-Beispiel:

Schreiben Sie 2 Js-Skripte wie folgt:

en-GB.js
lang = {
    date_message: 'The start date is incorrect',
    ...
};
es-ES.js
lang = {
    date_message: 'Fecha de inicio incorrecta',
    ...
};

Serverseite - Code hinter: 

Protected Overrides Sub InitializeCulture()
    Dim sLang As String 
    sLang = "es-ES" 

    Me.Culture = sLang
    Me.UICulture = sLang
    Page.ClientScript.RegisterClientScriptInclude(sLang & ".js", "../Scripts/" & sLang & ".js")

    MyBase.InitializeCulture()
End Sub

Wo sLang "en-GB" sein könnte, wissen Sie je nach Auswahl des aktuellen Benutzers ...

Javascript-Anrufe:

alert (lang.date_message);

Und es funktioniert sehr einfach, denke ich.

1
Caveman

Erweiterung auf Antwort von diodeus.myopenid.com: Lassen Sie Ihren Code eine Datei mit einem JS-Array mit allen erforderlichen Zeichenfolgen ausschreiben, und laden Sie die entsprechende Datei/das entsprechende Skript vor dem anderen JS-Code. 

0
Lasar