آموزش چند زبانه کردن سایت در ASP.NET
بسم الله الرحمن الرحیم
یکی از ویژگی هایی که در برنامه های تجاری بسیار مورد استفاده قرار می گیرد، ویژگی چند زبانه بودن نرم افزار است. این ویژگی در حال حاضر بسیار مورد اهمیت می باشد.
در وب سایت های مختلف می توانید مقالات متعددی را به همراه روش های متفاوتی در خصوص پیاده سازی چند زبانه کردن سیستم ها مشاهده کنید. در اینجا قصد داریم یکی از سریعترین روش ها و روش های پیشنهادی مایکروسافت برای طراحی یک وب سایت چند زبانه مورد استفاده قرار دهیم.
این مقاله می تواند هم برای کسانی که قصد طراحی وب سایت چند زبانه با APS.NET MVC دارند و هم کسانی که از ASP.NET Web Form استفاده می کنند مورد استفاده قرار گیرد.
قبل از شروع کار بهتر است برخی از مفاهیم این تکنولوژی را معرفی کنیم.
Internationalization
Internationalization یا به اختصار i18n، به فرایند تولید و توسعه محصولات نرم افزاری به گونه که محصول مورد نظر دارای قابلیت شخصی سازی و localization را داشته باشد گویند. localization در واقع به معنای پیاده سازی یک سیستم نرم افزار بر اساس زبان و فرهنگ (languages and cultures) یک کشور است.
Internationalization را به اختصار i18n می گویند که عدد 18 تعداد کاراکتر هایی است که مابین حرف i و n قرار گرفته است.
Globalization and Localization
Globalization
Globalization که به صورت مخفف ان را G11n می نامند، Globalization در واقع به فرایند تولید و توسعه نرم افزار می باشد که به وسیله آن محصول نهایی را برای فرهنگ های مختلف (cultures) مورد استفاد قرار داد.
cultures به فرمت تاریخ، واحد پول، نمایش اعداد و... گفته می شود، طبیعتا شما نیز تا کنون در ویندوز خود تاریخ و ساعت و واحد پول خود را از طریق Control Panel تغییر داده اید.
Globalization به اختصار G11n نامیده می شود، عدد 11 تعداد کاراکتر های مابین دو کاراکتر G و N می باشد.
Localization
Localization که به اختصار آن را L10n می نامند، به فرایند تولید و توسعه یک نرم افزار به گونه ای که بتوان آن را برای یک فرهنگ (culture) خاص شخص سازی (customize) کرد Localization می گویند.
Localization را به اختصار L10n می نامند، عدد 10 در اینجا نیز مانند سایر موارد تعداد حروفی است که مابین دو کاراکتر L و N قرار گرفته می باشد.
Culture in ASP.NET Framework
ASP.NET framework دو culture دارد، Culture و UICulture، مقادیر این دو culture از دو حرف کوچک برای تعریف زبان (language) و از دو حرف بزرگ برای تعریف منطقه جغرافیایی (region) تشکیل می شوند.
به طور مثال برای تعریف زبان انگلیسی از "en" و برای مشخص کردن منطقه انگلیس (Britain) و یا امریکا (American) بودن به ترتیب از "GB", "US" استفاده می شود.
پس اگر شما بخواهید نرم افزار خود را برای British English تنظیم کنید باید از en-GB استفاده کنید و همچنین اگر بخواهید از American English استفاده کنید باید از en-US استفاده کنید. با استفاده از این دو پارامتر در واقع شما می توانید فرمت تاریخ، پول و اعداد ( date, number, and currency) خود را تنظیم کنیم.
ما با دو مفهوم در پیاده سازی چند زبانه کردن نرم افزار ها روبرو هستیم:
Culture
تاریخ، ساعت، واحد پول و.. که می بایست بر اساس Culture انتخاب شده نمایش داده شود.
UICulture
فایل resource ایی که برای نمایش صحیح Culture کاربر می بایست انتخاب شود و اطلاعات از آن واکشی شود.
ASP.NET globalization framework
هر thread (در فارسی ریسمان معنا شده است به هر پردازشی که برنامه شما از آن بهره می گیرد، می گویند. به صورت پیش فرض هر برنامه تنها با یک thread طراحی می شود) NET. یک پراپرتی CurrentCulture و CurrentUICulture دارد.
این property ها در زمان Render شدن صفحه و مقادیر مرتبط با Culture توسط ASP.NET globalization framework استفاده می شوند.
Internationalization of Validation Messages
برای نمایش پیام ها به زبان های مختلف می بایست به ازای هر زبان پیام خود را ترجمه کنید و با یک کلید مشخص به ازای هر culture ذخیره کنید.
بسم الله الرحمن الرحیم
یکی از ویژگی هایی که در برنامه های تجاری بسیار مورد استفاده قرار می گیرد، ویژگی چند زبانه بودن نرم افزار است. این ویژگی در حال حاضر بسیار مورد اهمیت می باشد.
در وب سایت های مختلف می توانید مقالات متعددی را به همراه روش های متفاوتی در خصوص پیاده سازی چند زبانه کردن سیستم ها مشاهده کنید. در اینجا قصد داریم یکی از سریعترین روش ها و روش های پیشنهادی مایکروسافت برای طراحی یک وب سایت چند زبانه مورد استفاده قرار دهیم.
این مقاله می تواند هم برای کسانی که قصد طراحی وب سایت چند زبانه با APS.NET MVC دارند و هم کسانی که از ASP.NET Web Form استفاده می کنند مورد استفاده قرار گیرد.
قبل از شروع کار بهتر است برخی از مفاهیم این تکنولوژی را معرفی کنیم.
Internationalization
Internationalization یا به اختصار i18n، به فرایند تولید و توسعه محصولات نرم افزاری به گونه که محصول مورد نظر دارای قابلیت شخصی سازی و localization را داشته باشد گویند. localization در واقع به معنای پیاده سازی یک سیستم نرم افزار بر اساس زبان و فرهنگ (languages and cultures) یک کشور است.
Internationalization را به اختصار i18n می گویند که عدد 18 تعداد کاراکتر هایی است که مابین حرف i و n قرار گرفته است.
Globalization and Localization
Globalization
Globalization که به صورت مخفف ان را G11n می نامند، Globalization در واقع به فرایند تولید و توسعه نرم افزار می باشد که به وسیله آن محصول نهایی را برای فرهنگ های مختلف (cultures) مورد استفاد قرار داد.
cultures به فرمت تاریخ، واحد پول، نمایش اعداد و... گفته می شود، طبیعتا شما نیز تا کنون در ویندوز خود تاریخ و ساعت و واحد پول خود را از طریق Control Panel تغییر داده اید.
Globalization به اختصار G11n نامیده می شود، عدد 11 تعداد کاراکتر های مابین دو کاراکتر G و N می باشد.
Localization
Localization که به اختصار آن را L10n می نامند، به فرایند تولید و توسعه یک نرم افزار به گونه ای که بتوان آن را برای یک فرهنگ (culture) خاص شخص سازی (customize) کرد Localization می گویند.
Localization را به اختصار L10n می نامند، عدد 10 در اینجا نیز مانند سایر موارد تعداد حروفی است که مابین دو کاراکتر L و N قرار گرفته می باشد.
Culture in ASP.NET Framework
ASP.NET framework دو culture دارد، Culture و UICulture، مقادیر این دو culture از دو حرف کوچک برای تعریف زبان (language) و از دو حرف بزرگ برای تعریف منطقه جغرافیایی (region) تشکیل می شوند.
به طور مثال برای تعریف زبان انگلیسی از "en" و برای مشخص کردن منطقه انگلیس (Britain) و یا امریکا (American) بودن به ترتیب از "GB", "US" استفاده می شود.
پس اگر شما بخواهید نرم افزار خود را برای British English تنظیم کنید باید از en-GB استفاده کنید و همچنین اگر بخواهید از American English استفاده کنید باید از en-US استفاده کنید. با استفاده از این دو پارامتر در واقع شما می توانید فرمت تاریخ، پول و اعداد ( date, number, and currency) خود را تنظیم کنیم.
ما با دو مفهوم در پیاده سازی چند زبانه کردن نرم افزار ها روبرو هستیم:
Culture
تاریخ، ساعت، واحد پول و.. که می بایست بر اساس Culture انتخاب شده نمایش داده شود.
UICulture
فایل resource ایی که برای نمایش صحیح Culture کاربر می بایست انتخاب شود و اطلاعات از آن واکشی شود.
ASP.NET globalization framework
هر thread (در فارسی ریسمان معنا شده است به هر پردازشی که برنامه شما از آن بهره می گیرد، می گویند. به صورت پیش فرض هر برنامه تنها با یک thread طراحی می شود) NET. یک پراپرتی CurrentCulture و CurrentUICulture دارد.
این property ها در زمان Render شدن صفحه و مقادیر مرتبط با Culture توسط ASP.NET globalization framework استفاده می شوند.
Internationalization of Validation Messages
برای نمایش پیام ها به زبان های مختلف می بایست به ازای هر زبان پیام خود را ترجمه کنید و با یک کلید مشخص به ازای هر culture ذخیره کنید.
برای درک بهتر این قابلیت ها یک پروژه با دو زبان فارسی و انگلیسی پیاده سازی خواهیم کرد، culture پیش فرض برنامه ما "en" خواهد بود.
در این پروژه ما یک Soltion خواهیم داشت که این Soltion دو پروژه دارد، یکی پروژه ASP.NET MVC می باشد و دیگری یک پروژه از نوع Class Library که فقط متن های پیام ها، عنوان ها و سایر اطلاعات مختلف را برای هر زبان در آن ذخیره می کنیم.
برای ذخیره متن ها برای هر یک از زبان های مورد نیاز از فایل های Resource استفاده می کنند، این فایل ها با پسوند resx معرفی می شوند و سه مقدار را در هر رکورد می توان به صورت ذخیره کرد.
Name برای دسترسی به اطلاعات
Value برای ذخیره سازی مقدار مورد نظر شما
Comment
در همین پروژه و کمی جلوتر با این فایل کار خواهیم کرد و با آنها آشنا خواهید شد.
ما دو فایل Resource را ایجاد خواهیم کرد. یکی برای زبان فارسی و دیگری برای زبان انگلیسی، سپس در برنامه خود به جای نوشتن متن ها، خطاها و... به صورت مستقیم (به این کار Hard Code گفته میشود) آنها را از فایل Resource می خوانیم همین امر باعث می شود با تغییر زبان سایت کل متنها تغییر داده شود.
فکر می کنم توضیحات کافی می باشد و بهتر است برنامه خود را شروع کنیم.
Visual Studio خود را باز کنید و از قسمت File گزینه New Project را انتخاب کنید، سپس گزینه Web را انتخاب و نام پرژوه را Globalization را انتخاب و Ok کنید.
در پنجره باز شده تنظیمات را به صورت زیر تغییر داده (تنظیمات پیش فرض را تایید کنید) و سپس Ok کنید.
ساختار پروژه ما به صورت زیر خواهد بود.
حال بر روی Solution خود راست کلیک کنید تا یک پروژه دیگر برای اضافه کردن فایل های Resource جهت ثبت متن های مختلف برای هر زبان ایجاد کنیم.
از قسمت سمت چپ گزینه #Visual C را انتخاب و از قسمت انواع پروژه نوع Class Library را انتخاب کنید و سپس نام پروژه را ViewResources انتخاب کنید و سپس Ok کنید.
ساختار پروژه شما اکنون باید به صورت زیر باشد.
حال بر روی پروژه ViewResources کلیک راست کنید و از منوی Add-> New Item را انتخاب کنید. از پنجره باز شده از سمت چپ گزینه Code و از انواع فایل های قابل انتخاب نهایتا گزینه Resource را انتخاب کنید. نام فایل خود را Resource.fa.resx انتخاب کنید و سپس Add را انتخاب کنید.
مجددا مسیر بالا را طی کنید، این بار نام فایل را Resource.resx انتخاب کنید.
ساختار پروژه شما باید به صورت زیر باشد.
فایل های Resource باز کنید و اطلاعات زیر را در آن ثبت کنید.
فایل Resource.fa.resx
فایل Resource.resx
دقت کنید که حتما Access Modifier بر روی گزینه Public باشد در غیر این صورت برنامه شما نمی تواند مقادیر این فایل ها را بخواند
در نهایت می بایست Refrence پروژه مربوط به Resource را به پروژه Globalization اضافه نمایید.
هنگامی که چندین پروژه در یک Solution ایجاد می کنید می بایست مشخص کنید که هر پروژه به چه پروژه های دیگری می تواند دسترسی داشته باشد. ما در اینجا دو پروژه داریم و تنها Globalization می خواهد به پروژه Resource دسترسی داشته باشد.
بر روی پروژه Globalization کلیک راست کنید، سپس گزینه Add-> Refrence را انتخاب کنید.
در پنجره باز شده بر روی گزینه Solution در سمت چپ کلیک کنید و از سمت راست تیک پروژه ViewResource را زده و بر روی Ok کلیک کنید.
به پروژه Globalization که کدهای MVC ما در آنجا قرار دارد باز می گردیم.
بر روی Folder مربوط به Model راست کلیک کرده گزینه Add-> New Item را انتخاب کنید تا پنجره زیر باز شود، سپس گزینه Class را از پنجره باز شده انتخاب و نام آن را User انتخاب کنید و در نهایت گزینه Add را انتخاب کنید.
کدهای زیر را درون Model خود Paste کنید.
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Globalization.Models
{
public class User
{
[Display(Name = "Username", ResourceType = typeof(ViewResources.Resource))]
[Required(ErrorMessageResourceName = "UsernameRequired", ErrorMessageResourceType = typeof(ViewResources.Resource))]
public string Username { get; set; }
[Display(Name = "Name", ResourceType = typeof(ViewResources.Resource))]
[Required(ErrorMessageResourceName = "NameRequired", ErrorMessageResourceType = typeof(ViewResources.Resource))]
public string Name { get; set; }
[Display(Name = "Password", ResourceType = typeof(ViewResources.Resource))]
[Required(ErrorMessageResourceName = "PasswordRequired", ErrorMessageResourceType = typeof(ViewResources.Resource))]
public string Password { get; set; }
[Display(Name = "ConfirmPassword", ResourceType = typeof(ViewResources.Resource))]
[Required(ErrorMessageResourceName = "ConfirmPasswordRequired", ErrorMessageResourceType = typeof(ViewResources.Resource))]
[Compare("Password", ErrorMessageResourceName = "ConfirmPasswordCompare", ErrorMessageResourceType = typeof(ViewResources.Resource))]
public string ConfirmPassword { get; set; }
[Display(Name = "Address", ResourceType = typeof(ViewResources.Resource))]
[Required(ErrorMessageResourceName = "AddressRequired", ErrorMessageResourceType = typeof(ViewResources.Resource))]
public string Address { get; set; }
}
}
تنها نکته جدیدی که در کدهای بالا قرار دارد، وجود کد زیر است
, ResourceType = typeof(ViewResources.Resource))]
این کد برای مشخص کردن متن هایی است که باید بر روی View نمایش داده شود، به صورت پیش فرض ما متن های خود را دستی نیز ثبت کرده ایم اما اگر کاربر Resource متفاوتی را انتخاب کند متن های عنوان، پیام ها و... با توجه Resource زبانی که کاربر انتخاب کرده است تغییر خواهد کرد.
به درون فایل Index در قسمت View های Home بروید و کدهای زیر را در آن قرار دهید.
@model Globalization.Models.User
@{
ViewBag.Title = ViewResources.Resource.Title;
}
<div class="row">
<div class="col-md-5">
<h2>@ViewResources.Resource.Title</h2>
</div>
<div class="col-md-7">
@using (Html.BeginForm("ChangeCulture", "Home"))
{
<p>
@ViewResources.Resource.SelectLanguage : @Html.DropDownList("ddlCulture", new SelectList(new[]
{
new{value="en",text=ViewResources.Resource.English},
new{value="fa",text=ViewResources.Resource.Persian}
}, "value", "text", Session["CurrentCulture"]), new { onchange = "this.form.submit();" })
</p>
}
</div>
</div>
<br />
@using (Html.BeginForm("Index", "Home"))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Username, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Username, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Username, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.PasswordFor(model => model.Password, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.PasswordFor(model => model.ConfirmPassword, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Address, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextAreaFor(model => model.Address, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Address, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="@ViewResources.Resource.Save" class="btn btn-default" />
</div>
</div>
</div>
}
چند نکته در کدهای بالا مشخص است:
1- ما عنوان صفحه را به صورت زیر نوشته ایم
ViewBag.Title = ViewResources.Resource.Title;
این کار باعث خواهد شد عنوان صفحه بر اساس زبانی که کاربر انتخاب می کند تغییر داده شود.
2- عنوان مشخص شده در صفحه نیز بر اساس زبان انتخاب شده مانند بالا تغییر خواهد کرد.
<h2>@ViewResources.Resource.Title</h2>
3- یک Dropdown برای انتخاب زبان توسط کاربر به صورت زیر تعریف شده است.
@using (Html.BeginForm("ChangeCulture", "Home"))
{
<p>
@ViewResources.Resource.SelectLanguage : @Html.DropDownList("ddlCulture", new SelectList(new[]
{
new{value="en",text=ViewResources.Resource.English},
new{value="fa",text=ViewResources.Resource.Persian}
}, "value", "text", Session["CurrentCulture"]), new { onchange = "this.form.submit();" })
</p>
}
در کد بالا گزینه ای که توسط کاربر انتخاب شده است برای کنترلر POST خواهد شد که کد Post شدن اطلاعات را در بخش بعد در Controller بررسی خواهیم کرد.
4- کد Button ما به صورت زیر نوشته شده است:
<input type="submit" value="@ViewResources.Resource.Save" class="btn btn-default" />
همانطور که مشاهده می کنید عنوان این Button نیز از Resource خوانده می شود بنابراین با تغییر زبان وب سایت عنوان این نیز به زبانی که کاربر انتخاب شده است تغییر داده می شود.
به کد View مجددا دقت کنید. همانطور که مشاهده می کنید، ما نامی از فیلد Resourcce نبرده ایم، مثلا برای Username ننوشته ایم که از Resource.Username بخوان!!
ASP.NET MVC بر اساس نام فیلد که در اینجا Username می باشد مقدار مورد نظر آن را در فایل Resourcce معرفی شده پیدا خواهد کرد پس در نام گذاری فیلدهای Resourcce می بایست دقت نمایید.
سایر کدهای این صفحه مانند صفحات عادی دیگری هستند که شما آنها را طراحی می کنید.
در نهایت کافی است که کد HomeContoroller را به صورت زیر تغییر دهید. کدهای زیر را به HomeContoroller خود اضافه نمایید:
/** changing culture*/
public ActionResult ChangeCulture(string ddlCulture)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo(ddlCulture);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(ddlCulture);
Session["CurrentCulture"] = ddlCulture;
return View("Index");
}
/**initilizing culture on controller initialization*/
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
base.Initialize(requestContext);
if (Session["CurrentCulture"] != null)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo(Session["CurrentCulture"].ToString());
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Session["CurrentCulture"].ToString());
}
}
[HttpPost]
public ActionResult Index(Globalization.Models.User user)
{
return View();
}
متد اول مربوط به Dropdown می باشد، در صورتی که کاربر مقداری را در Dropdown انتخاب کند این مقدار در این متد بررسی و در Session ذخیره می شود و همچنین باعث می شود متد بعدی که در زمان Initialize اجرا می شود، اجرا شده و بر اساس مقدار درون Session فایل Resource مرتبط با زبان انتخاب شده توسط کاربر Load شود. در نهایت با Load شدن فایل جدید تمام متن ها به زبان انتخاب شده کاربر تغییر داده می شوند.
Resource.fa.resx فایلی است که متن های برنامه را برای زبان فارسی نمایش خواهد داد و فایل Resource.resx متنهای مربوط به زبان انگلیسی را نمایش می دهد. Resource.resx فایل پیش فرض بوده و در ابتدا برنامه با زبان انگلیسی اجرا می شود.
در نهایت خروجی برنامه ما به صورت زیر خواهد بود:
همچنین شما برای تغییر قالب صفحه می توانید با Load کردن فایل های CSS متفاوت مشکل راست چین و چپ چین کردن سایت را نیز مرتفع کنید.
پوریا ادیب فر
سلام و درود
navidsalajegheh
با سلام و تشکر بابت مقاله عالی شما من از این روش استفاده کردم ، خیلی واضح و قابل فهم بود سوالی که دارم در مورد اخرین جمله در مقاله شما هستش : "همچنین شما برای تغییر قالب صفحه می توانید با Load کردن فایل های CSS متفاوت مشکل راست چین و چپ چین کردن سایت را نیز مرتفع کنید." میشه در این مورد هم لطف کنید و توضیحات بیشتری بنویسید یا اگه امکان داره این مورد رو هم به مقاله بالا اضافه کنید که کامل باشه بازم تشکر
اسماعیلشیدایی
با عرض سلام
از اینکه توانستیم وظایف خودمان را نسبت به شما دوستان عزیز به خوبی انجام دهیم بسیار خرسندیم.
پاسخ سوال شما)
هنگامی که شما زبان یک وب سایت را تغییر می دهید انتظار دارید مکان عناصر صفحه نیز تغییر داده شوند (فارسی راست به چپ و مثلا زبان انگلیسی چپ به راست) حال اگر این اتفاق رخ ندهد، ظاهر سایت شما به هم ریخته خواهد شد.
برای حل این مشکل شما باید دو فایل css را داشته باشید تا بر اساس انتخاب زبان یکی از آنها لود شود مطمئنا اگر سایت شما با Bootstrap طراحی شده باشد، اینکار را می توانید خیلی ساده با لود کردن فایل های bootstrap.css و bootstrap-rtl.css انجام دهید.
در مورد ارائه ی یک آموزش نیز انشالله در اولین فرصت این مبحث را نیز به صورت کامل آموزش خواهیم داد.
Mostafa
سلام
مهندس من از این روش استفاده کردم ولی مشکلی که دارم من می خوام زبان پیش فرض فارسی باشه ولی در هر صورت زبان رو انگلیسی میذاره چطور می تونم توی پروژه اطلاعات دیتابیس رو هم با این روش فیلتر کنم یعنی چطور به زبان فعلی دسترسی داشته باشم
اسماعیلشیدایی
با سلام
منظور شما ا ز اینکه می فرمایید زبان کالربر را تشخیص دهم متوجه نمی شوم. اما برای تغییر زبان باید از یک url استفاده کنید مثلا انتهای نام دامنه ی خود عبارت fa یا en را قرار دهید و بر اساس آن اطلاعات را لود کنید.
موفق باشید