niedziela, 15 maja 2011

Wilojęzyczność w ASP.NET MVC

Kiedyś pisałem o globalizacji w ASP.NET WebForms (link). Jako, że ostatnimi czasy bardziej interesuje się MVC postanowiłem przenieść tamtą idę do nowego środowiska.

Na początek ustawmy środowisko testowe naszej aplikacji.
Jako przeglądarki użyję IE9. Aby zmienić w niej wyświetlany język wybieramy kolejno opcje internetowe a następnie na zakładce Ogólne w dziale Wygląd opcje Języki. Ja dodałem tutaj język angielski:



Należy pamiętać, że kolejność języków ma znaczenie. Najwyżej powinien się znajdować język preferowany lub jeżeli użytkownik nie ustawił innego, język który jest używany lokalnie w danym rejonie.

Aby odczytać język używany przez przeglądarkę użytkownika wystarczy zastosować prostą konstrukcję:


Code:
string[] languages = Request.UserLanguages;

Warto zauważyć tutaj ciekawą rzecz a mianowicie:


W niektórych przypadkach otrzymujemy tzw. kwalifikator (q=0.5) tak więc próbując przesłać takie dane np. do konstruktora CultureInfo() otrzymamy wyjątek. Dlatego powyższa linijka powinna wyglądać w następujący sposób:


Code:
string mainLanguage = Request.UserLanguages[0].Split(';')[0];

Mając informacje odnośnie preferowanego przez użytkownika języka, możemy przystąpić do projektowania interfejsu użytkownika.

Wielojęzyczność można osiągnąć na kilka sposobów. W zależności czy mamy do czynienia z statyczną stroną w której treść się nie zmienia czy też jest to strona na której często dodajemy newsy wybierzemy odpowiedni sposób. Jeżeli mamy do czynienia z stroną statyczną możemy skorzystać z resourców (zasobów). Jeżeli korzystamy ze strony na której często zmienia się treść (np. blogu) w takim przypadku należy przygotować odpowiednią strukturę w bazie danych, która pozwoli na przechowywanie artykułów w kilku językach.

Przedstawię tutaj prostszą wersję nadającą się świetnie dla prostych, statycznych stron.

W celach demonstracyjnych stworzymy prosty projekt zawierający jedną stronę oraz MasterPage na którym umieścimy powitanie na stronie w odpowiednim języku. Nasz projekt będzie mieć następującą strukturę:


Projekt jest więc bardzo prosty. Aby skorzystać z dobrodziejstw zasobów należy stworzyć strukturę odpowiadającą obecnej strukturze:


Po wypełnieniu wartościami kopiujemy nasz zasób i tworzymy odpowiednie nazwy związane z nazwą języka:


Dla każdego z języków powtarzamy taką samą operację.

Teraz przejdziemy do wyświetlenia odpowiedniej informacji na stronie w odpowiednim języku. W naszym MasterPage-u zmieniamy zawartość z:


Code:
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
</head>
<body>
    <div>
        <h1>Witaj na stronie</h1>
    </div>
    <div>
        <asp:ContentPlaceHolder ID="MainContent" runat="server">
        
        </asp:ContentPlaceHolder>
    </div>
</body>
</html>

na:


Code:
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
</head>
<body>
    <div>
        <h1><%: MvcApplication3.Resources.Shared.MasterPage.Greatings %></h1>
    </div>
    <div>
        <asp:ContentPlaceHolder ID="MainContent" runat="server">
        
        </asp:ContentPlaceHolder>
    </div>
</body>
</html>

Następnie należy wczytać odpowiedni język ustawiony w przeglądarce użytkownika. W tym celu w pliku Global.asax dodajemy następującą metodę:


Code:
protected void Application_BeginRequest(object sender, EventArgs e)
        {
            if (Request.UserLanguages.Length > 0)
            {
                string language = Request.UserLanguages[0].Split(';')[0];
                if (language.Contains("en"))
                {
                    Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("en");       
                }
            }
        }

Po tym zabiegu nasza strona w zależności od ustawień przeglądarki użytkownika będzie wyświetlała powitanie w języku polskim bądź też angielskim.
Rozwiązanie nadaje się do wyświetlania stałych elementów strony. Jak wspominałem wcześniej do wyświetlania artykułów należy skorzystać z dobrze zaprojektowanej bazy danych.

1 komentarz:

  1. Solidnie napisane. Pozdrawiam i liczę na więcej ciekawych artykułów.

    OdpowiedzUsuń