Najlepsze praktyki dotyczące lokalizacji i globalizacji ciągów znaków i etykiet [zamknięte]

124

Jestem członkiem zespołu składającego się z ponad 20 programistów. Każdy programista pracuje nad osobnym modułem (około 10 modułów). W każdym module możemy mieć co najmniej 50 formularzy CRUD, co oznacza, że ​​obecnie mamy blisko 500 przycisków dodawania , zapisywania , edycji itp.

Ponieważ jednak chcemy zglobalizować naszą aplikację, musimy mieć możliwość tłumaczenia tekstów w naszej aplikacji. Na przykład wszędzie słowo add powinno stać się ajouterem dla francuskich użytkowników.

To, co zrobiliśmy do tej pory, to to, że dla każdego widoku w interfejsie użytkownika lub warstwie prezentacji mamy słownik par klucz / wartość w tłumaczeniach. Następnie podczas renderowania widoku tłumaczymy wymagane teksty i napisy za pomocą tego słownika. Jednak to podejście, doszliśmy do około 500 dodatków w 500 słownikach. Oznacza to, że złamaliśmy zasadę DRY.

Z drugiej strony, jeśli scentralizujemy typowe ciągi znaków, na przykład umieszczając add w jednym miejscu, i poprosimy programistów, aby używali go wszędzie, napotkamy problem braku pewności, czy ciąg jest już zdefiniowany w scentralizowanym słowniku, czy nie.

Inną opcją może być brak słownika tłumaczeń i korzystanie z usług tłumaczeniowych online, takich jak Tłumacz Google, Tłumacz Bing itp.

Innym problemem, który napotkaliśmy, jest to, że niektórzy programiści pod presją dostarczenia projektu na czas nie pamiętają kluczy tłumaczenia . Na przykład w przypadku tekstu przycisku dodawania programista użył dodania, podczas gdy inny programista użył nowego itp.

Jaka jest najlepsza lub najbardziej znana metoda globalizacji i lokalizacji zasobów ciągów aplikacji?

Mouneer
źródło
2
Rozmowa przez Alex Sexton na temat Client Side Internacjonalizacja z konferencji JS UE to dobry początek.
Minko Gechev

Odpowiedzi:

51

O ile wiem, localeplanetw JavaScript istnieje dobra biblioteka o nazwie Localization and Internationalization. Ponadto uważam, że jest natywny i nie ma żadnych zależności od innych bibliotek (np. JQuery)

Oto strona biblioteki: http://www.localeplanet.com/

Spójrz również na ten artykuł Mozilli, możesz znaleźć bardzo dobrą metodę i algorytmy tłumaczenia po stronie klienta: http://blog.mozilla.org/webdev/2011/10/06/i18njs-internationalize-your-javascript-with- a-little-help-from-json-and-the-server /

Wspólnym elementem wszystkich tych artykułów / bibliotek jest to, że używają i18nklasy i getmetody (w pewnym sensie również określających obszar mniejszy nazwę funkcji podobnego _) do pobierania / konwersji keydo value. W moim wyjaśnieniu keyoznacza, że ​​łańcuch, który chcesz przetłumaczyć, i valueoznacza przetłumaczony ciąg.
Następnie potrzebujesz tylko dokumentu JSON do przechowywania plików key„i value”.

Na przykład:

var _ = document.webL10n.get;
alert(_('test'));

A tutaj JSON:

{ test: "blah blah" }

Uważam, że korzystanie z aktualnych, popularnych rozwiązań bibliotecznych jest dobrym podejściem.

Afshin Mehrabani
źródło
1
Bez obrazy, ale czy nie tego próbował już Afshin? Jego problem polega na tym, że różni programiści mają trudności z zapamiętaniem, których kluczy użyć. Zgadzam się z tym, że opisana przez Ciebie metoda jest drogą do zrobienia. Nie rozumiem, jak mogłoby być inaczej. Dzięki za świetne linki przy okazji.
Spock,
47

Kiedy stajesz przed problemem do rozwiązania (i szczerze mówiąc, kto nie jest obecnie?), Podstawowa strategia, którą zwykle przyjmujemy my, komputerowcy, nazywa się „dziel i rządź”. To wygląda tak:

  • Konceptualizuj konkretny problem jako zbiór mniejszych podproblemów.
  • Rozwiąż każdy mniejszy problem.
  • Połącz wyniki w rozwiązanie konkretnego problemu.

Jednak „dziel i rządź” nie jest jedyną możliwą strategią. Możemy również przyjąć bardziej ogólne podejście:

  • Postrzegaj konkretny problem jako szczególny przypadek bardziej ogólnego problemu.
  • Jakoś rozwiązać ogólny problem.
  • Dostosuj rozwiązanie ogólnego problemu do konkretnego problemu.

- Eric Lippert

Uważam, że istnieje już wiele rozwiązań tego problemu w językach po stronie serwera, takich jak ASP.Net/C#.

Przedstawiłem kilka głównych aspektów problemu

  • Problem : musimy załadować dane tylko dla żądanego języka

    Rozwiązanie : W tym celu zapisujemy dane w osobnych plikach dla każdego języka

dawny. res.de.js, res.fr.js, res.en.js, res.js (dla języka domyślnego)

  • Problem: pliki zasobów dla każdej strony powinny być oddzielone, abyśmy otrzymali tylko potrzebne dane

    Rozwiązanie : Możemy użyć niektórych narzędzi, które już istnieją, takich jak https://github.com/rgrove/lazyload

  • Problem: potrzebujemy struktury par klucz / wartość, aby zapisać nasze dane

    Rozwiązanie : sugeruję obiekt javascript zamiast string / string air. Możemy czerpać korzyści z inteligencji w IDE

  • Problem: Członkowie generalni powinni być przechowywani w pliku publicznym, a wszystkie strony powinny mieć do nich dostęp

    Rozwiązanie : w tym celu tworzę folder w katalogu głównym aplikacji internetowej o nazwie Global_Resources i folder do przechowywania pliku globalnego dla każdego podfolderów, które nazwaliśmy „Local_Resources”

  • Problem: każdy członek podsystemu / podfolderu / modułu powinien zastąpić elementy członkowskie Global_Resources w swoim zakresie

    Rozwiązanie : rozważałem plik dla każdego

Struktura aplikacji

root/
    Global_Resources/
        default.js
        default.fr.js
    UserManagementSystem/
        Local_Resources/
            default.js
            default.fr.js
            createUser.js
        Login.htm
        CreateUser.htm

Odpowiedni kod dla plików:

Global_Resources / default.js

var res = {
    Create : "Create",
    Update : "Save Changes",
    Delete : "Delete"
};

Global_Resources / default.fr.js

var res = {
    Create : "créer",
    Update : "Enregistrer les modifications",
    Delete : "effacer"
};

Plik zasobów dla żądanego języka powinien zostać załadowany na stronie wybranej z Global_Resource - powinien to być pierwszy plik ładowany na wszystkich stronach.

UserManagementSystem / Local_Resources / default.js

res.Name = "Name";
res.UserName = "UserName";
res.Password = "Password";

UserManagementSystem / Local_Resources / default.fr.js

res.Name = "nom";
res.UserName = "Nom d'utilisateur";
res.Password = "Mot de passe";

UserManagementSystem / Local_Resources / createUser.js

// Override res.Create on Global_Resources/default.js
res.Create = "Create User"; 

UserManagementSystem / Local_Resources / createUser.fr.js

// Override Global_Resources/default.fr.js
res.Create = "Créer un utilisateur";

plik manager.js (ten plik powinien być ładowany jako ostatni)

res.lang = "fr";

var globalResourcePath = "Global_Resources";
var resourceFiles = [];

var currentFile = globalResourcePath + "\\default" + res.lang + ".js" ;

if(!IsFileExist(currentFile))
    currentFile = globalResourcePath + "\\default.js" ;
if(!IsFileExist(currentFile)) throw new Exception("File Not Found");

resourceFiles.push(currentFile);

// Push parent folder on folder into folder
foreach(var folder in parent folder of current page)
{
    currentFile = folder + "\\Local_Resource\\default." + res.lang + ".js";

    if(!IsExist(currentFile))
        currentFile = folder + "\\Local_Resource\\default.js";
    if(!IsExist(currentFile)) throw new Exception("File Not Found");

    resourceFiles.push(currentFile);
}

for(int i = 0; i < resourceFiles.length; i++) { Load.js(resourceFiles[i]); }

// Get current page name
var pageNameWithoutExtension = "SomePage";

currentFile = currentPageFolderPath + pageNameWithoutExtension + res.lang + ".js" ;

if(!IsExist(currentFile))
    currentFile = currentPageFolderPath + pageNameWithoutExtension + ".js" ;
if(!IsExist(currentFile)) throw new Exception("File Not Found");

Mam nadzieję, że to pomoże :)

Omid Shariati
źródło
7
Jedyne, co mi się nie podoba w tym podejściu, to to, że lokalizacja i programowanie są ze sobą ściśle powiązane ... Więc kiedy dodawany jest ciąg w języku angielskim (niezależnie od tego, jaki jest domyślny), pozostałe języki muszą zostać zaktualizowane poprzez kod. Wolałbym mieć JSON utworzony za pomocą narzędzia z jakiegoś pliku tłumaczeń. Wciąż dobra reprezentacja!
Nate-Wilkins
zrobiłeś to samo, co w przypadku lokalizacji, możesz zobaczyć, że w zapytaniu: stackoverflow.com/q/53864279/4061006 . Jedyną rzeczą jest to, w jaki sposób tłumaczysz Global_Resources / default.js na Global_Resources / default.fr.js? Jakiego narzędzia / zestawu używasz do konwersji tych plików na żądane języki. Ponieważ ja też tego potrzebuję
Jayavel,
Obok każdego klucza należy przechowywać komentarz w postaci czytelnej dla człowieka, opisujący, dokąd przechodzi ciąg i co oznacza, aby zapewnić tłumaczowi (lub sobie) więcej kontekstu, gdy idziesz dodać nowy język i zapomniałeś, o czym oznacza ciągi. Zrób coś takiego, "Create" : {"message": "Create", "description": "text on the button that opens the editor with a blank Foo"}jak na przykład dla lokalizacji rozszerzeń Chrome . Lub utwórz oddzielny plik zawierający te komentarze.
Boris
13

jQuery.i18n to lekka wtyczka jQuery umożliwiająca umiędzynarodowienie stron internetowych. Umożliwia pakowanie niestandardowych ciągów zasobów w plikach „.properties”, podobnie jak w pakietach zasobów Java. Ładuje i analizuje pakiety zasobów (.properties) na podstawie dostarczonego języka lub języka zgłaszanego przez przeglądarkę.

aby dowiedzieć się więcej na ten temat, zajrzyj do artykułu Jak umiędzynarodowić swoje strony za pomocą JQuery?

BalaKrishnan 웃
źródło
Link zniknął
Alexander Farber