Võ Văn Hải's blog

Chỉ có một điều tuyệt đối đó là mọi thứ đều tương đối…

Localization – Internationalization (Địa phương hóa – Quốc tế hóa

Ngày nay, với đà phát triển của ứng dụng tin học, việc tạo 1 ứng dụng (win/web) đòi hỏi đa ngôn ngữ trở nên hết sức cần thiết. Trong bài viết này, tôi sẽ hướng dẫn các bạn tạo ra 1 ứng dụng căn bản giải quyết vấn đề này.

Nói chung, có rất nhiều kỹ thuật được đặt ra. Tôi sẽ giời thiệu sô bộ vài kỹ thuật:

1.  Dùng database để lưu các trường chứa các mẫu tin cho các ngôn ngữ khác nhau. Cách này chậm.

2. Dùng file các file XML để lưu các ngôn ngữ khác nhau rồi tùy theo người dùng chọn ngôn ngữ nào bạn dùng DOM (chẳng hạn) lấy ra node rồi hiển thị.

3. Cách này hay hơn cả – đó là dùng localization trong C# (internationalization trong java).

4. Cách này bèo nhất – Tạo 2 ứng dụng (web)  giống nhau nhưng cho 2 ngôn ngữ khác nhau.

5. …

Nói chung tùy theo mong muốn / sở thích của bạn mà viết. Ở đây tôi sẽ hướng dẫn bạn dùng cách thứ 3 (localization) để viết 1 ứng dụng/ web đa ngôn ngữ.


A. Với window Application

Ở đây tôi dùng ngôn ngữ C#, IDE là VS 2008
1.

Tạo 1 project (C#) có tên WindowsFormsApplication_Localization.

Tạo 1 form mới có tên là frmTestLocalization. Thiết kế như hình sau (nhớ đặt tên các controls như các giá trị text trong controls, còn giá trị text là gì không cần thiết)
localization_wf_cs_02.png
2.

Trong cửa sổ Project Explorer, nhấn chuột phải lên project, chọn Add -> New Item, chọn Resource File, đặt tên là SampleResource.resx như hình:
ocalization_wf_cs_01.png
Sau đó nhấn OK .

Nhập các giá trị cho resx này như hình sau:
localization_wf_cs_en.png

Chú ý: Cột Name chính là tên của các controls của chúng ta và cột value chính là giá trị của thuộc tính text.
3.

Tạo các file resources khác tương ứng với các ngôn ngữ mà bạn cần. Ở đây tôi tạo thêm 3 ngôn ngữ là tiếng Pháp, Tiếng Tây Ban Nha, Tiếng Việt (không biết ngôn ngữ thì lên google mà translate🙂 )

Tên của các resource file phải bắ đầu với tên củaResource mặc định sau đó đến .culture-language:

Các file tương ứng của chúng ta sẽ là:

  • SampleResource.es-ES.resx
  • SampleResource.fr-FR.resx
  • SampleResource.vi.resx

Riêng em VI thì khác🙂

localization_wf_cs_fr.png

localization_wf_cs_es.png

localization_wf_cs_vi.png
Chú ý em tiếng Việt này: Culture của nó chỉ là vi. Nếu chọn vi-VN sẽ không được hỗ trợ, vì sao hổng biết????

Bạn có thể xem liệt kê các ngôn ngữ hỗ trợ trong NetFX ở bài viết:  Liệt kê các tên culture và các định danh trong C#

4.

Cấu trúc Project của ứng dụng chúng ta như hình sau:

localization_wf_cs_03.png

5. Code cho Form

Bạn phải khai báo sử dụng các thư viện sau

using System.Resources;
using System.Globalization;
using System.Threading;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Resources;
using System.Globalization;
using System.Threading;

namespace WindowsFormsApplication_Localization
{
public partial class frmTestLocalization : Form
{
private ResourceManager m_ResourceManager =
new ResourceManager(“WindowsFormsApplication_Localization.SampleResource”,
System.Reflection.Assembly.GetExecutingAssembly());
private CultureInfo m_EnglishCulture = new CultureInfo(“en-US”);
private CultureInfo m_FrenchCulture = new CultureInfo(“fr-FR”);
private CultureInfo m_SpanishCulture = new CultureInfo(“es-ES”);
private CultureInfo m_VietnameCulture =new CultureInfo(“vi”);

public frmTestLocalization()
{
InitializeComponent();
}
/// <summary>
/// Cập nhật UI
/// </summary>
private void UpdateUI()
{
lblFirstName.Text = m_ResourceManager.GetString(“lblFirstName”);
lblLastName.Text = m_ResourceManager.GetString(“lblLastName”);
lblChoose.Text = m_ResourceManager.GetString(“lblChoose”);
btnGreetMe.Text = m_ResourceManager.GetString(“btnGreetMe”);
radEnglish.Text = m_ResourceManager.GetString(“radEnglish”);
radFrench.Text = m_ResourceManager.GetString(“radFrench”);
radSpanish.Text = m_ResourceManager.GetString(“radSpanish”);
radVietnamese.Text = m_ResourceManager.GetString(“radVietnamese”);
this.Text = m_ResourceManager.GetString(“formTitle”);
}
private void CheckSupportLanguages()
{
if (m_ResourceManager.GetResourceSet(m_FrenchCulture, true, false) == null)
{
radFrench.Enabled = false;
}
if (m_ResourceManager.GetResourceSet(m_SpanishCulture, true, false) == null)
{
radSpanish.Enabled = false;
}
if (m_ResourceManager.GetResourceSet(m_VietnameCulture, true, false) == null)
{
radVietnamese.Enabled = false;
}
}

private void frmTestLocalization_Load(object sender, EventArgs e)
{
CheckSupportLanguages();
Thread.CurrentThread.CurrentUICulture = m_EnglishCulture;
UpdateUI();
}

private void Language_CheckedChanged(object sender, EventArgs e)
{
CultureInfo cul=null;
if (radEnglish.Checked == true)
cul = m_EnglishCulture;
else if (radFrench.Checked == true)
cul = m_FrenchCulture;
else if (radSpanish.Checked == true)
cul = m_SpanishCulture;
else if (radVietnamese.Checked == true)
cul = m_VietnameCulture;

Thread.CurrentThread.CurrentUICulture = cul;
UpdateUI();
}

private void btnGreetMe_Click(object sender, EventArgs e)
{
string message = String.Format(m_ResourceManager.GetString(“greetingMessage”),
txtFirstNameMB.Text, txtLastNameMB.Text);
MessageBox.Show(this, message, this.Text, MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
}
}

Kết quả thực thi:
localization_wf_cs_04.png

13 Responses to “Localization – Internationalization (Địa phương hóa – Quốc tế hóa”

  1. Nguyễn Trung Dũng said

    Em chào thầy,
    Em xin phép được có ý kiến thế này, nếu chúng ta dùng Resource để lưu thông tin, thì việc mở rộng cho đa ngôn ngữ sau này sẽ kém đi. Lý do, chúng ta phải thao tác trực tiếp với source code. Nhưng với XML thì chúng ta có thể sử dụng kỹ thuật Plug-in, cho file XML một ngôn ngữ nào đó thì chương trình sẽ tự nhận ra mà không cần đụng chạm gì đến suorce nguyên thủy.
    Nếu có sai xót, mong thầy hướng dẫn thêm cho em. Em xin chúc thầy được dồi dào sức khỏe và thành công!

    Học trò của thầy, Trung Dũng

  2. Ngô Quốc Tuấn said

    Em cũng đồng ý với bạn Trung Dũng và góp ý thêm như sau : nếu dùng Resource thì mỗi lần thêm thì phải mở IDE lên mới thêm được và Resource chỉ dùng đa ngôn ngữ trên UI mà thôi còn data phía dưới cũng chỉ có 1 ngôn ngữ.
    Còn đáp ứng cho cả UI và nội dung để đa ngôn ngữ thì kết hợp cả Database vào nữa là Ok.
    Em chỉ có ý kiến vậy thôi.

    Cựu SV.

  3. Hung said

    Em chào thầy. Sao bài này chỉ hướng dẫn Localization – Internationalization cho C# không vậy thầy, thầy có thể hướng dẫn cho em bằng JAVA được không thầy. Em xin cảm ơn thầy nhiều. E chỉ cần 2 ngôn ngữ English và Dutch.

  4. Leon said

    Chào thầy!
    Em thử làm theo hướng dẫn của thầy nhưng khi biên dịch lại báo lỗi “Could not find any resources appropriate for the specified culture or the neutral culture. Make sure “Form1.DaNguHoaResources” was correctly embedded or linked into assembly “Danguhoa” at compile time, or that all the satellite assemblies required are loadable and fully signed.”
    Thầy có thể chỉ em biết tại sao bị như vậy ko ạ.
    Cảm ơn thầy.

  5. LamHa said

    Còn web thì làm thế nào vậy thầy.

  6. anlvan said

    Thầy ơi, cái này cũng khá hay. Em đã tập làm được nhưng giờ có một vấn đề là làm sao mình có thể lưu lại ngôn ngữ đã chọn. Chứ hiện tại bây giờ mỗi khi chạy lên thì nó là tiếng Anh chọn lại ngôn ngữ khác thì form ngay tức thì đổi ngôn ngữ theo như mình chọn nhưng khi mình thoát ứng dụng sau đó mở lên lại thì nó cũng là tiếng Anh.

  7. Võ Văn Hải said

    Bạn có thể dùng cookie để lưu lựa chọn của người dùng tại máy của họ. Khi chạy trang web lên, bạn lấy cookie, nếu mà có thì chọn ngôn ngữ theo người dùng, còn không thì mặc định là 1 ngôn ngữ do bạn chọn.

  8. thanhnt said

    Vấn đề ngôn ngữ – em cũng từng làm qua. Cách em sử dụng tương tự như cách thứ 2 của thầy. Nhưng nó được tổ chức lại với cấu trức khác mà ko dùng resource. sử dụng file nhưng không phải xml.
    Em chưa so sách tốc độ xủa lý của resource so với cách em sẽ trình bày – nhưng về mặt khả thi và tiện lợi có thể tốt hơn.
    (ở đây đưa ra ý tưởng – mọi người có thể code lại – đang lang thang tìm tài liệu giải quyết vấn đề nên ko code được)
    + Xây dựng một class với mục đích lưu trử id và mean, tạm gọi language.
    + xây dựng một class với mục đích lưu trữ danh sách các ngôn ngữ, tạm gọi languagelist.
    => mục đích để tạo ra giao diện để quản lý ngôn ngữ riêng, nó sẽ được đống gói thành 1 tool – vì khi bán phần mềm ở việt nam hoặc mỹ, chúng ra desing 2 language. Nếu khách hàng China mua thì thế nào – phải build lại, nên nếu tổ chức tool – khi có yêu cầu về ngôn ngữ mới, chúng ta sẽ mở tool lên và thêm vào languagelist một ngôn ngữ China và thêm vào tưng id với china mean. và update soft là okO( nói vậy chứ còn nhiều chỗ phải làm lắm: như trên soft phải có chức năng lựa chọn ngôn ngữ, vì đây là mutilanguage cho soft,….)
    + Xây dựng một lớp hỗ trợ read-write object đến file, sử dụng mã hóa dữ liệu.
    Nguyên tắc hoạt động:
    + Khi một giao diện được mởi nó phải được thay đổi language trong lúc khởi tạo

    + Dựa vào id để lấy mean. Nên chúng ta sẽ dễ dàng thay đổi mean của một text dễ dàng và linh động.

  9. thanh hải said

    Thầy cho em hỏi là, nếu chúng ta ứng dụng trong Webform thì dưới đây sửa lại như thế nào
    private ResourceManager m_ResourceManager =
    new ResourceManager(“WindowsFormsApplication_Localization.SampleResource”,
    System.Reflection.Assembly.GetExecutingAssembly());

  10. Kieu Hai said

    Chào thầy, em đang có một số thắc mắc về i18n , với demo vừa trên của thầy thì mới chỉ localization được giao diện bao ngoài của ứng dụng thôi, nhưng đối với việc localization dữ liệu trong database, thì có giải pháp trên có còn tính khả thi không? nếu thầy đọc được comment của em, thì xin thầy cho em xin một vài lời khuya ạ. Mail của em là dioxinbaby@yahoo.com.vn . Nếu được xin thầy gửi cho em một vài gợi ý.

  11. Võ Văn Hải said

    trên 1 số lớp học thầy đã demo dùng với xml, dùng với databse. tuy nhiên thầy chưa có tóm lược lại để đưa lên blog. Chắc là hẹn 1 ngày gần đây chứ bây giờ mình đang làm luận án nên chưa có thời gian.

  12. […] https://vovanhai.wordpress.com/c/localization-internationalization-d%E1%BB%8Ba-ph%C6%B0%C6%A1ng-hoa-q… […]

  13. Pham Xuan Giang said

    Very good

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: