Rozwijam interfejs użytkownika dla aplikacji .NET MVC, która w najbliższej przyszłości będzie wymagać międzynarodowej lokalizacji całej zawartości. Zasadniczo jestem dobrze zaznajomiony z .NET, ale nigdy nie miałem projektu, który wymagałby tak znacznego skupienia się na międzynarodowej dostępności.
Prognozowany jest początkowo w języku angielskim. Jakie środki należy podjąć w tym miejscu, aby ułatwić wdrożenie lokalizacji w przyszłości?
.net
localization
internationalization
multilingual
smartcaveman
źródło
źródło
Odpowiedzi:
Tworzysz aplikację ASP.Net MVC, prawda? Inne odpowiedzi wydają się być specyficzne dla aplikacji komputerowych. Pozwól mi uchwycić wspólne rzeczy:
Wykrywanie ustawień regionalnych
Bardzo ważne jest, aby aplikacja poprawnie wykrywała lokalizację użytkownika. W aplikacji komputerowej CultureInfo.CurrentCulture posiada preferowane ustawienia formatowania (ten, który powinien być używany do formatowania liczb, dat, walut itp.), Podczas gdy CultureInfo.CurrentUICulture posiada preferowane ustawienia regionalne interfejsu użytkownika (ten, który powinien być używany do wyświetlania zlokalizowanych wiadomości) . W przypadku aplikacji internetowych należy ustawić obie kultury na automatyczne (aby automatycznie wykrywać ustawienia regionalne z nagłówka AcceptLanguage), chyba że chcesz wdrożyć jakiś wymyślny proces wykrywania ustawień regionalnych (tj. Chcesz obsługiwać zmianę języka na żądanie).
Zewnętrzne ciągi znaków
Wszystkie ciągi powinny pochodzić z zasobów, czyli plików Resx. W aplikacji Winforms można to łatwo osiągnąć, ustawiając właściwość Form Localizable na true. Będziesz także musiał ręcznie (niestety) eksternalizować ciągi, które pochodzą z twoich modeli. Jest to również stosunkowo proste. W Asp.Net trzeba ręcznie wszystko uzewnętrznić ...
Układy
Zdecydowanie musisz zezwolić na rozszerzenie łańcucha. W świecie Winforms jest to możliwe dzięki TableLayoutPanel, którego należy użyć, aby upewnić się, że układ dostosuje się automatycznie, aby uwzględnić dłuższy tekst. W świecie internetowym masz trochę szczęścia. Może być konieczne wdrożenie mechanizmu lokalizacji CSS - sposobu modyfikowania (zastępowania) definicji CSS. Umożliwiłoby to pracownikom Lokalizacji modyfikowanie problemów dotyczących stylu na żądanie. Upewnij się, że każdy element HTML na renderowanej stronie ma unikalny identyfikator - pozwoli to na precyzyjne ukierunkowanie.
Problemy specyficzne dla kultury
Unikaj używania grafiki, kolorów i dźwięków, które mogą być specyficzne dla kultury zachodniej. Jeśli naprawdę tego potrzebujesz, podaj środki lokalizacji. Unikaj grafiki kierunkowej (ponieważ byłby to problem przy próbie lokalizacji w języku arabskim lub hebrajskim). Nie zakładaj też, że cały świat używa tych samych liczb (tj. Nie jest to prawda w przypadku języka arabskiego).
ToString () i Parse ()
Pamiętaj, aby zawsze przekazywać CultureInfo podczas wywoływania ToString (), chyba że nie jest ono obsługiwane. W ten sposób komentujesz swoje zamiary. Na przykład: jeśli używasz jakiegoś numeru wewnętrznie i z jakiegoś powodu musisz go przekonwertować na ciąg znaków:
W przypadku numerów, które będą wyświetlane użytkownikom:
To samo dotyczy Parse (), TryParse (), a nawet ParseExact () - niektóre nieprzyjemne błędy można wprowadzić bez właściwego użycia CultureInfo. To dlatego, że jakaś biedna dusza w Microsoft, pełna dobrych intencji, zdecydowała, że warto traktować CultureInfo.CurrentCulture jako domyślną (byłaby użyta, jeśli niczego nie przekażesz) - w końcu, gdy ktoś używa ToString ( ) chce wyświetlić go użytkownikowi, prawda? Okazało się, że nie zawsze tak jest - na przykład spróbuj zapisać numer wersji aplikacji w bazie danych, a następnie przekonwertuj go na instancję klasy Version. Powodzenia.
Daty i strefy czasowe
Pamiętaj, aby zawsze przechowywać i tworzyć DateTime w UTC (użyj DateTime.UtcNow zamiast DateTime.Now). Konwertuj go na czas lokalny w formacie lokalnym po wyświetleniu:
Jeśli chcesz wysyłać wiadomości e-mail z odniesieniem do czasu w treści, pamiętaj o podaniu informacji o strefie czasowej - uwzględnij zarówno przesunięcie UTC, jak i listę miast:
Wiadomości złożone
Zostałeś już ostrzeżony, aby nie łączyć łańcuchów. Zamiast tego prawdopodobnie użyłbyś String.Format () jak pokazano powyżej. Muszę jednak stwierdzić, że należy zminimalizować użycie wiadomości złożonych. Jest tak dlatego, że reguły gramatyki docelowej są dość często różne, więc tłumacze mogą potrzebować nie tylko zmienić kolejność zdań (byłoby to rozwiązane za pomocą symboli zastępczych i String.Format ()), ale tłumaczyć całe zdanie w inny sposób na podstawie co zostanie podstawione. Pozwól, że podam kilka przykładów:
Inne problemy konkatenacji
Łączenie nie ogranicza się do łańcuchów. Unikaj układania kontroli razem, powiedz:
Przypomnij mi jeszcze raz w [polu tekstowym z liczbą] dni.
Powinno to zostać zmienione na coś w stylu: Przypomnij mi ponownie za tę liczbę dni: [pole tekstowe].
Kodowanie znaków i czcionki
Zawsze zapisuj, przesyłaj, dowolny tekst w Unicode (tj. W UTF-8). Nie koduj czcionek na stałe - Lokalizacja może wymagać ich modyfikacji, a to wyłączy domyślny mechanizm cofania czcionek (w przypadku Winforms). Pamiętaj, aby dopuścić „dziwne” znaki w większości pól (tj. Nazwa użytkownika).
Test
Prawdopodobnie będziesz musiał wdrożyć tak zwane pseudo tłumaczenie, czyli utworzyć zasoby dla powiedzmy niemieckiej kultury i skopiować swoje angielskie ciągi znaków, dodając prefiks i sufiks. Możesz także zawijać symbole zastępcze, aby łatwo wykrywać ciągi złożone. Celem pseudo tłumaczenia jest wykrycie problemów związanych z lokalizowalnością, takich jak zakodowane ciągi, problemy z układem i nadmierne użycie komunikatów złożonych.
źródło
String.Format
aby mógł obsługiwać tę fajną składnię:"There {0:was|were} {0} {0:virus|viruses} found."
każdy język może ładować własne reguły, więc możesz to zrobić"Znaleziono {0} {0:wirusy|wirusów}."
Źródło znajduje się na GitHub: github.com/scottrippey/SmartFormat/wiki"{0} {0:plik|pliki|plików}"
. Formatyzator ma polską regułę, która określa, który z 3 formularzy ma zostać użyty, i poprawnie określa przypadki specjalne. Obecnie pracuję nad dodaniem kolejnych reguł, więcgettext
artykuł okaże się bardzo przydatny, dziękuję.Kilka podstawowych rzeczy, które powinieneś wziąć pod uwagę:
Zewnętrznie wszystkie zasoby ciągów
Wszystkie zasoby powinny być zawarte w plikach zewnętrznych, które można przekazać do lokalizacji. Nie zapomnij o komunikatach o błędach, jeśli chcesz je również zlokalizować.
Pozostaw wystarczającą ilość miejsca na rozwinięcie łańcucha
Ciągi w niektórych językach są na przykład do 30% dłuższe (na przykład grecki), więc upewnij się, że projektujesz interfejs w taki sposób, aby w razie potrzeby ciągi mogły się rozwijać. Oto dość ekstremalny przykład dla francuskiego:
Jako punkt wyjścia polecam wykonanie jakiegoś pseudo tłumaczenia ( http://en.wikipedia.org/wiki/Pseudolocalization ). Lub możesz przetłumaczyć swoje zasoby za pomocą Tłumacza Google lub Bing. To da ci dobrą wskazówkę, jak będą wyglądać rzeczywiste tłumaczenia.
Uważaj na tekst w obrazach
Jeśli używasz żadnych obrazów w aplikacji - upewnij się, że nie zawierają one tekstu - to oczywiście nie może zostać przetłumaczone.
Nigdy nie koduj na stałe ścieżek do folderów Windows
Oczywiście, ale widziałem to w przeszłości. Na przykład
C:\Program Files
jest tłumaczony na niektóre międzynarodowe wersje systemu Windows, np.C:\Programme
Na niemiecki system operacyjny.Unikaj używania terminów specyficznych dla regionu
Na przykład, jeśli poprosisz kogoś o „szkołę średnią” na formularzu, nie ma to większego znaczenia w zachodniej Europie.
Unikaj tworzenia łańcuchów poprzez łączenie łańcuchów
Na przykład wygląda to nieszkodliwie:
Ale kolejność słów na przykład w języku japońskim byłaby inna, więc może to nie mieć żadnego sensu.
Ustawienia godziny / daty
Zawsze upewnij się, że format czasu / daty pochodzi z systemu operacyjnego.
źródło
Specjalne uwagi dla języków azjatyckich
Oprócz wszystkich wspaniałych odpowiedzi, które już tu są, należy zwrócić uwagę na języki azjatyckie:
Uważaj na różne długości tekstu
Tekst w języku chińskim i koreańskim jest zwykle znacznie krótszy niż tekst w języku angielskim (ponieważ zwykle potrzeba mniej znaków blokowych, aby napisać to samo), więc strona może wyglądać na pustą po chińsku, ale wypełniona po niemiecku ... Musisz to zrobić niektóre dynamiczne zmiany rozmiaru, aby dobrze wyglądać.
Jednak tekst japoński zwykle jest znacznie dłuższy, nawet dłuższy niż równoważny tekst angielski pod względem liczby znaków.
Uważaj na układ podstawowy i wygląd „przesuwany w górę”
Znaki azjatyckie są zwykle układane na linii podstawowej , która nie obejmuje zstępników (tj. Dolnej części y, g, q, j itd.) Podczas formatowania elementu ekranowego - zwykle przycisków - z tekstem w środku, a jeśli to tekst to tylko języki azjatyckie (tzn. brak alfabetów zachodnich), wówczas tekst będzie wyglądał, jakby został przesunięty w górę.
Formatowanie liczb i zlokalizowane jednostki liczbowe
Formatuj liczby inaczej. Różne kraje azjatyckie mają różne sposoby formatowania liczb. To samo dotyczy walut. Na przykład w Azji Wschodniej 10.000 (wan) jest wspólną jednostką. W Indiach powszechne jest 100 000 (lakhs).
Lokalne waluty
Waluty niektórych krajów mają wiele zer i nie mają przecinka dziesiętnego (np. Japonia, Indonezja, Włochy), podczas gdy inne mają do dwóch cyfr po przecinku.
Uważaj na różne porządki słów
Kolejność słów może nie zawsze być taka sama. Najlepiej jest używać {0}, {1} itd. W formatowaniu ciągów zamiast porządkowania wyrazów, jeśli łańcuch pochodzi z kombinacji różnych elementów danych.
Użyj sortowania specyficznego dla ustawień regionalnych
Sortowanie jest różne w zależności od języka i regionu - zawsze powinieneś polegać na specyficznym dla regionu systemie sortowania.
Zachowaj ostrożność przy znakach o pełnej / połowie szerokości
Uważaj na różnice między znakami „pełnej szerokości” i „połowy szerokości”. Nawiasy klamrowe, interpunkcyjne itp. Mogą mieć wersje „pełnej szerokości”, które różnią się od standardowych ASCII. Jeśli przeszukujesz lub dzielisz ciągi znaków na podstawie tych liter, musisz najpierw przekonwertować wszystkie symbole o pełnej szerokości na ekwiwalenty połowy szerokości.
Kropka nie jest kropką ... przecinek nie jest przecinkiem ...
Uważaj na gotcha do wprowadzania danych - na przykład w języku chińskim kropka nie jest kropką „.”. Przecinek ma pełną szerokość, a nie „,”. Nie próbuj szukać zachodniej interpunkcji, jeśli użytkownik wprowadzający dane może przypadkowo włączyć edytor IME języka azjatyckiego.
Numery telefoniczne
Nie zakładaj niczego w formatowaniu numeru telefonu. Nie zawsze istnieje numer kierunkowy itp. I można go sformatować inaczej. Zwykle mają ciąg formatu dla każdego kraju.
Nie zakładaj, że ludzie będą mieli tylko jeden numer telefonu komórkowego lub jeden numer faksu itp. W Azji tak nie jest.
Adresy - gęstsze niż myślisz
W przypadku adresów nie zakładaj niczego . Nie zawsze może być kod pocztowy. Kody pocztowe nie zawsze mogą być cyframi. Kraj może nie mieć prowincji / stanów. Kraj może być po prostu dużym miastem (np. Singapur). W niektórych krajach azjatyckich najmniejszą jednostką domu może być „Pokój X, Jednostka Y, Sekcja Z, Piętro A, Blok B, Grupa C, Osiedle D”. Ogólnie rzecz biorąc, bądź bardzo liberalny pod względem liczby pól i liczby znaków dozwolonych w adresach.
Pozdrowienia
Pozdrowienia są nie tylko ograniczać się do pana, pani itd. Mimo, że prawdopodobnie jesteś bezpieczny w użyciu „M” i „F” na seks - nie są to jednak dziwne ...
źródło
Niektóre podstawowe kroki mają na celu upewnienie się, że dowolny ciąg wyświetlany na ekranie nie jest literałem w kodzie. Jeśli robisz Winforms, każdy formularz będzie miał zasób interfejsu użytkownika. W przypadku okien dialogowych, raportów itp. Upewnij się, że korzystasz z plików zasobów projektu.
Więc zamiast „Przesyłanie nie powiodło się” w kodzie, możesz mieć coś takiego jak Resources.UploadFailed
W ten sposób możesz utworzyć nowy plik zasobów dla każdego używanego języka (i .Net pomoże w tym.) I mieć zlokalizowany ciąg w każdym pliku.
EDYCJA Zapomniałem wspomnieć, kiedy robisz swój interfejs użytkownika, upewnij się, że nie tylko wkuwasz tam rzeczy. W zależności od języka, w którym się znajdujesz, problem może stanowić nieruchomość. Pracowałem nad projektem, w którym niemiecki i portugalski byli 2 największymi sprawcami wzrostu strun. Gdybyśmy nie byli ostrożnymi ciągami, które byłyby w porządku w języku angielskim, francuski i włoski wybuchłyby w języku niemieckim.
źródło
Sugeruję, abyś uruchomił FXCop lub Visual Studio Code Analysis (są całkiem takie same) na swoich złożeniach.
Są dobrzy w wykrywaniu kodu .NET, który nie wykorzystuje odpowiednich przeciążeń zorientowanych na kulturę, takich jak ten: CA1305: Określ IFormatProvider .
Muszę dodać, że te narzędzia są również frustrujące, ponieważ zwykle wykrywają zyliony problemów w kodzie, ale mimo to, nawet jeśli nie przestrzegasz każdej reguły, powinieneś dużo się nauczyć.
źródło
Oprócz konkretnego sposobu ładowania zasobów upewniam się, że najpierw testujesz w pseudo-zlokalizowanej wersji. W przeciwnym razie prawdopodobnie nie zauważysz miejsc, w których do końca pomijano względy internacjonalizacji.
źródło
Oprócz wszystkich innych pomocnych wskazówek, oto kilka brakujących:
Weź pod uwagę, że niektóre kraje używają więcej niż jednego języka. Na przykład w Kanadzie użytkownik spodziewałby się, że będzie mógł łatwo przełączać się między językiem angielskim a francuskim.
Jeśli zadajesz użytkownikowi pytanie wymagające odpowiedzi na jedną literę, nie oczekuj od użytkownika naciśnięcia klawisza „Y”, aby powiedzieć „tak”.
Bądź bardzo świadomy w przechowywanych procesach, że daty w SQL DB są w formacie USA
Umieszczenie ciągów tekstowych w bazie danych pozwala później dodać dodatkowe języki bez konieczności ponownego wdrażania.
Wysyłając pisemne pliki tekstowe do tłumaczenia, zawsze dołącz opis kontekstu, aby upewnić się, że tłumacz wybierze właściwe słowo. Np. Bez kontekstu możesz przetłumaczyć „pitch:” na coś związanego z dźwiękiem lub miejsce, w którym grasz w piłkę nożną
Etykiety adresowe zawsze wymagają konwersji. Prowincja w Kanadzie, stan w Ameryce, hrabstwo w Wielkiej Brytanii
źródło
Musisz wziąć pod uwagę:
Routing dla wielu języków
Przenieś cały ciąg kodu twardego do pliku zasobów
Przykład właściwości:
Model:
Widok:
źródło
Oto coś, o czym nie wspomnieliśmy w pozostałych odpowiedziach.
W zależności od złożoności aplikacji i jej lokalizacji, zdecydowanie zaleciłbym wdrożenie alternatywnego dostawcy zasobów i przechowywanie zlokalizowanych zasobów w bazie danych. Przy domyślnym schemacie lokalizacji ASP.NET wszystkie zasoby są przechowywane w plikach RESX, które:
Jako możliwy przykład zastosowania rozważ dostarczenie pakietów językowych dla swojej aplikacji oraz możliwość importowania i eksportowania języków za pośrednictwem interfejsu użytkownika. Pliki RESX by tu nie pomogły.
W takich sytuacjach alternatywny dostawca zasobów jest bardzo pomocny. Więcej informacji na temat implementacji można znaleźć tutaj . Oczywiście jest to rzadki przypadek częściej spotykany w aplikacjach korporacyjnych, ale nadal aktualny.
źródło
Najważniejsze jest zarządzanie treścią w różnych językach. Sam opracowałem kilka stron internetowych, a zarządzanie treściami w różnych językach jest największym wyzwaniem.
Korzystam z bazy danych do przechowywania zasobów / treści. Daje mi elastyczność dodawania dowolnego wsparcia językowego, jakiego chcę. Wdrożyłem logikę powrotu do języka angielskiego, jeśli nie znaleziono zasobu w danym języku.
Później możesz użyć tłumacza, aby przekonwertować wartość angielską na dowolny język.
źródło
Podsumowanie rzeczy, które należy wziąć pod uwagę przy internacjonalizacji:
Wszystkie informacje powinny być umiędzynarodowione. Weź pod uwagę, że grafika może zawierać informacje, które chcemy internacjonalizować.
Rozmiar pól lub ciągów, w zależności od języka, ponieważ może to spowodować nam problem.
Kolejność słów zależy od tego, w jakim języku jesteśmy, więc kolejność w jednym języku będzie taka sama w innym.
Musimy wziąć pod uwagę, że format daty zmieni się z jednego języka na inny
źródło
Wykonaj test w Turcji :
Jeśli Twoja witryna / program działa dobrze z klientem tureckim, możesz być pewien, że będzie działał na większości innych platform.
źródło