من میخوام یک مجموعه از applicationهای تحت وب داشته باشم که همگی یک نوع طراحی UI داشته باشند و یک منو کلی داشته باشم که کاربرها بتون از اون به هریک از applicationها هدایت بشوند منتها چند نکته وجود داره :
- همه این برنامهها به لحاظ عملکردی یکسری مشترکات دارند ( مثلا احراز هویت ، لیست کاربرها و ....)
- هر کدوم از این برنامهها باید بتونن مستقل طراحی بشن در عین حال که از یک شکل ui استفاده میکنند
- به راحتی بتونم یک برنامه به مجموعه برنامه هام اضافه کنم یا یکی ازش کم کنم یا یکی را غیر فعال کنم ( باید معماری scalable باشد
به نظر شما روش ارائه شده در این صفحه بدرد من میخوره؟
اگر نه از چه معماری استفاده کنم؟
خطا و راهنمایی
- نمیتونید از این کتابخانه یا کلاسهای مثالهای آن مستقیما در سیلورلایت استفاده کنید (could not be resolved in the currently targeted framework). نیاز است حتما از طریق یک وب سرویس اینکار انجام شود. در پوشه Samples\SlPdf سورسهای همراه کتابخانه یک مثال کامل در این مورد هست: ^
- مراجعه کنید به مثال طراحی برگه سؤالات امتحانی. شبیه به آن است. با هر دو حالت قابل انجام است: ^ و ^
ابتدا باید فضای نام System.Web.Routing را در فایل Global.asax اضافه کنیم .
protected void Application_Start(object sender, EventArgs e) { RouteTable.Routes.MapPageRoute("Product", "Product/{Name}", "~/Product.aspx"); }
RouteTable.Routes.MapPageRoute("PostDetail", "Post/{pi}/{pt}", "~/PostShow.aspx");
<a href='<%# string.Format("/Post/{0}/{1}",Eval("PostID"),Eval("PostTitle").ToString().Replace(" ","-")) %>'>
Post/12/چگونه-طراحان-وب-به-جهنم-می-روند!؟
int pi = int.Parse(Page.RouteData.Values["pi"].ToString()); Posts post = (from p in con.Posts where p.PostID == pi select p).FirstOrDefault();
<asp:EntityDataSource ID="EntityDataSource1" runat="server" AutoGenerateWhereClause="True" ConnectionString="name=WebWorkEntities" DefaultContainerName="WebWorkEntities" EnableFlattening="False" EntitySetName="Posts" EntityTypeFilter="Posts" Where="" Select=""> <WhereParameters> <asp:RouteParameter Name="PostID" RouteKey="pi" DbType="Int32" DefaultValue="0" /> </WhereParameters> </asp:EntityDataSource>
protected void Application_Start(object sender, EventArgs e) { RoutingSite(RouteTable.Routes); } public static void RoutingSite(RouteCollection route) { route.MapPageRoute("PostDetail", "Post/{pi}/{pt}", "~/PostShow.aspx"); route.MapPageRoute("RouteAbout", "About-Me", "~/About.aspx"); }
- تعدادی خصوصیت و فیلد و متد در کلاس وجود دارند که به نظر میرسد فقط باهم کار میکنند.
- زیر مجموعهای از دادههای کلاس، معمولا همراه هم تغییر میکنند یا به یکدیگر وابسته هستند.
- با تغییر بدنه متدی، نیاز شود متدهای دیگری در همان راستا تغییر کنند.
- ارث بریها تنها به صورت دستهای بر اعضای کلاس اثر میگذارند.
مراحل انجام این بازسازی کد
- تصمیم بگیرید که به چه صورت کلاسی را تقسیم خواهید کرد.
- کلاس جدیدی بسازید که نشان دهنده مسئولیتهای جدید تقسیم شده باشد. اگر نام کلاس قدیمی با مسئولیتهای باقی مانده برای آن همخوانی نداشت، نام آن را تغییر دهید
- فیلدها و خصوصیات کلاس قدیمی را با استفاده از بازسازی Move field به کلاس جدید منتقل نمایید.
- کد را برای هر انتقال کامپایل و تست نمایید.
- متدهای کلاس قدیمی را با استفاده از بازسازی جابجایی متد به کلاس جدید منتقل نمایید.
- کد را برای هر انتقال، کامپایل و تست نمایید.
public class InvoiceService { public void AddInvoice() { } public void DeleteInvoice() { } public void AddOfflinePayment(int invoiceId) { } public void AddOnlinePayment(int invoiceId) { } }
public class InvoiceService { public void AddInvoice() { } public void DeleteInvoice() { } } public class PaymentService { public void AddOfflinePayment(int invoiceId) { } public void AddOnlinePayment(int invoiceId) { } }
- تقسیم کلاسهای controller بر اساس قوانین طراحی REST
- تقسیم کلاسهای داده (data model) بر اساس قوانین شیءگرایی و تک وظیفگی
خواندنیهای 4 شهریور
آفیس
اس کیوال سرور
الگوهای طراحی برنامه نویسی شیءگرا
توسعه وب
دات نت فریم ورک
متفرقه
محیطهای مجتمع توسعه
مرورگرها
ویندوز
آشنایی با نحوه ایجاد یک IoC Container
- هدف از قسمت جاری آشنایی اولیه با مراحل ابتدایی کار با یک IoC Container است.
- در حالت اول هنوز شما هستید که مسئول وهله سازیهای اولیه میباشید و کار وهله سازی را به لایهای دیگر واگذار نکردهاید.
- در کد حالت اول نمیشود این وابستگی ارسالی به سازنده کلاس را به سادگی تعویض کرد. در حالیکه با استفاده از یک IoC container فقط کافی است تنظیمات اولیه نگاشتهای آنرا مشخص کنیم تا نوع کلاسی که باید در سازندهها تزریق شوند مشخص شود. مزیت اینکار سادهتر شدن نوشتن آزمونهای واحد و تهیه کلاسهای Fake است؛ بدون نیازی به تغییری حتی در حد یک سطر در کدهای اصلی برنامه.
- در مورد وهله سازی خودکار چند سطح وابستگیها، در قسمتهای بعد تحت عنوان Object graph بیشتر بحث شده است و مثال زده شده. همیشه با یک کلاس ساده ویزا مانند مثال فوق سر و کار نداریم. عموما با سرویسهایی سر و کار داریم که خودشان نیز از سرویسهای دیگری استفاده میکنند. برای مثال یک سرویس ارسال ایمیل از سرویس کاربران برای دریافت ایمیلهای کاربران کمک میگیرد. وهله سازی تمام این وابستگیها را در چند سطح میشود با استفاده از IoC Containers خودکار کرد و به کدهای نهایی بسیار تمیزتری رسید.
- در حالت اول، طول عمر یک شیء را نمیشود مشخص کرد (یا حداقل نیاز به کد نویسی قابل توجهی دارد). برای مثال با استفاده از یک IoC Container میشود وهله ایجاد شده را Singleton کرد تا در سراسر برنامه یک وهله از آن استفاده شود یا حتی میشود در طول یک درخواست رسیده وب، یک وهله را در اختیار تمام کلاسهای درگیر قرار داد. به این ترتیب به سربار کمتری در حالتهای خاصی مانند وهله سازی ObjectContext یا DbContext در EF خواهیم رسید.
- زمان استفاده از IoC Containerها کارهای فراتری از تزریق وابستگیها را هم میشود انجام داد. برای مثال فراخوانیهای متدها را هم تحت نظر قرار داد (برنامه نویسی AOP یا جنبه گرا) و مثلا بدون نوشتن کد اضافهای در برنامه، خروجی متدها را کش کرد. AOP یک سری بحث مفصل را در طی یک دوره جدا به همراه دارد.
واژه XSS مخفف Cross-site scripting، نوعی از آسیب پذیریست که در برنامههای تحت وب نمود پیدا میکند. به طور کلی و خلاصه، این آسیب پذیری به فرد نفوذ کننده اجازه تزریق اسکریپتهایی را به صفحات وب، میدهد که در سمت کاربر اجرا میشوند ( Client Side scripts ) . در نهایت این اسکریپتها توسط سایر افرادی که از صفحات مورد هدف قرار گرفته بازدید میکنند اجرا خواهد شد.
هدف از این نوع حمله :
بدست آوردن اطلاعات کوکیها و سشنهای کاربران ( مرتبط با آدرسی که صفحه آلوده شده در آن قرار دارد ) است. سپس فرد نفوذ کننده متناسب با اطلاعات بدست آمده میتواند به اکانت شخصی کاربران مورد هدف قرار گرفته، نفوذ کرده و از اطلاعات شخصی آنها سوء استفاده کند .
به صورت کلی دو طبقه بندی برای انواع حملات Cross-site scripting وجود دارند.
حملات XSS ذخیره سازی شده ( Stored XSS Attacks ) :
در این نوع ، کدهای مخرب تزریق شده، در سرور سایت قربانی ذخیره میشوند. محل ذخیره سازی میتواند دیتابیس سایت یا هر جای دیگری که دادهها توسط سایت یا برنامه تحت وب بازیابی میشوند و نمایش داده میشوند باشد. اما اینکه چگونه کدهای مخرب در منابع یاد شده ذخیره میشوند؟
فرض کنید در سایت جاری آسیب پذیری مذکور وجود دارد. راههای ارسال دادهها به این سایت چیست؟ نویسندگان میتوانند مطلب ارسال کنند و کاربران میتوانند نظر دهند. حال اگر در یکی از این دو بخش بررسیهای لازم جهت مقابله با این آسیب پذیری وجود نداشته باشد و نوشتههای کاربران که میتواند شامل کدهای مخرب باشد مستقیما در دیتابیس ذخیره شده و بدون هیچ اعتبار سنجی نمایش داده شود چه اتفاقی رخ خواهد داد؟ مسلما با بازدید صفحه آلوده شده، کدهای مخرب بر روی مرورگر شما اجرا و کوکیهای سایت جاری که متعلق به شما هستند برای هکر ارسال میشود و ...
حملات XSS منعکس شده ( Reflected XSS Attacks ) :
در این نوع از حمله، هیچ نوع کد مخربی در منابع ذخیره سازی وبسایت یا اپلیکیشن تحت وب توسط فرد مهاجم ذخیره نمیشود ! بلکه از ضعف امنیتی بخشهایی همچون بخش جستجو وب سایت، بخشهای نمایش پیغام خطا و ... استفاده میشود ... اما به چه صورت؟
در بسیاری از سایتها، انجمنها و سیستمهای سازمانی تحت وب، مشاهده میشود که مثلا در بخش جستجو، یک فیلد برای وارد کردن عبارت جستجو وجود دارد. پس از وارد کردن عبارت جستجو و submit فرم، علاوه بر نمایش نتایج جستجو، عبارت جستجو شده نیز به نمایش گذاشته میشود و بعضا در بسیاری از سیستمها این عبارت قبل از نمایش اعتبار سنجی نمیشود که آیا شامل کدهای مخرب میباشد یا خیر. همین امر سبب میشود تا اگر عبارت جستجو شامل کدهای مخرب باشد، آنها به همراه نتیجهی جستجو اجرا شوند.
اما این موضوع چگونه مورد سوء استفاده قرار خواهد گرفت؟ مگر نه اینکه این عبارت ذخیره نمیشود پس با توضیحات فوق، کد فقط بر روی سیستم مهاجم که کد جستجو را ایجاد میکند اجرا میشود، درست است؟ بله درست است ولی به نقطه ضعف زیر توجه کنید ؟
www.test.com/search?q=PHNjcmlwdD5hbGVydChkb2N1bWVudC5jb29raWUpOzwvc2NyaXB0Pg==
این آدرس حاصل submit شدن فرم جستجو وبسایت test (نام وبسایت واقعی نیست و برای مثال است ) و ارجاع به صفحه نتایج جستجو میباشد. در واقع این لینک برای جستجوی یک کلمه یا عبارت توسط این وبسایت تولید شده و از هر کجا به این لینک مراجعه کنید عبارت مورد نظر مورد جستجو واقع خواهد شد. در واقع عبارت جستجو به صورت Base64 به عنوان یک query String به وبسایت ارسال میشود؛ علاوه بر نمایش نتایج، عبارت جستجو شده نیز به کاربر نشان داده شده و اگر آسیب پذیری مورد بحث وجود داشته باشد و عبارت شامل کدهای مخرب باشد، کدهای مخرب بر روی مرورگر فردی که این لینک را باز کرده اجرا خواهد شد!
در این صورت کافیست فرد مهاجم لینک مخرب را به هر شکلی به فرد مورد هدف بدهد ( مثلا ایمیل و ... ). حال در صورتیکه فرد لینک را باز کند (با توجه به اینکه لینک مربوط به یک سایت معروف است و عدم آگاهی کاربر از آسیب پذیری موجود در لینک، باعث باز کردن لینک توسط کاربر میشود)، کدها بر روی مرورگرش اجرا شده و کوکیهای سایت مذکور برای مهاجم ارسال خواهد شد ... به این نوع حمله XSS ، نوع انعکاسی میگویند که کاملا از توضیحات فوق الذکر، دلیل این نامگذاری مشخص میباشد.
اهمیت مقابله با این حمله :
برای نمونه این نوع باگ حتی تا سال گذشته در سرویس ایمیل یاهو وجود داشت. به شکلی که یکی از افراد انجمن hackforums به صورت Private این باگ را به عنوان Yahoo 0-Day XSS Exploit در محیط زیر زمینی و بازار سیاه هکرها به مبلغ چند صد هزار دلار به فروش میرساند. کاربران مورد هدف کافی بود تا فقط یک ایمیل دریافتی از هکر را باز کنند تا کوکیهای سایت یاهو برای هکر ارسال شده و دسترسی ایمیلهای فرد قربانی برای هکر فراهم شود ... ( در حال حاظر این باگ در یاهو وجو ندارد ).
چگونگی جلوگیری از این آسیب پذیری
در این سری از مقالات کدهای پیرامون سرفصلها و مثالها با ASP.net تحت فریم ورک MVC و به زبان C# خواهند بود. هر چند کلیات مقابله با آسیب پذیری هایی از این دست در تمامی زبانها و تکنولوژیهای تحت وب یکسان میباشند.
خوشبختانه کتابخانهای قدرتمند برای مقابله با حمله مورد بحث وجود دارد با نام AntiXSS که میتوانید آخرین نسخه آن را با فرمان زیر از طریق nugget به پروژه خود اضافه کنید. البته ذکر این نکته حائز اهمیت است که Asp.net و فریم ورک MVC به صورت توکار تا حدودی از بروز این حملات جلوگیری میکند. برای مثال به این صورت که در View ها شما تا زمانی که از MvcHtmlString استفاده نکنید تمامی محتوای مورد نظر برای نمایش به صورت Encode شده رندر میشوند. این داستان برای Url ها هم که به صورت پیش فرض encode میشوند صدق میکند. ولی گاها وقتی شما برای ورود اطلاعات مثلا از یک ادیتور WYSWYG استفاده میکنید و نیاز دارید دادهها را بدون encoding رندر کنید. آنگاه به ناچار مجاب بر اعمال یک سری سیاستهای خاصتر بر روی داده مورد نظر برای رندر میشوید و نمیتوانید از encoding توکار فوق الذکر استفاده کنید. آنگاه این کتابخانه در اعمال سیاستهای جلوگیری از بروز این آسیب پذیری میتواند برای شما مفید واقع شود.
PM> Install-Package AntiXSS
… var reviewContent = model.UserReview; reviewContent = Microsoft.Security.Application.Encoder.HtmlEncode(review); …
امیدوارم در اولین بخش از این سری مقالات، به صورت خلاصه مطالب مهمی که باعث ایجاد فهم کلی در رابطه با حملات Xss وجود دارد، برای دوستان روشن شده و پیش زمینه فکری برای مقابله با این دست از حملات برایتان به وجود آمده باشد.
- طراحی دیتابیس یا بانک اطلاعاتی بر پایه چند زبانه بودن و بررسی سناریوهای مختلف.
- نکاتی که باید در ساخت سایتهای چند زبانه به آنها دقت کرد.
- شیوهی تشخیص و تغییر زبان سایت
- معرفی چند کامپوننت وب، برای مباحث چند زبانه
طراحی مدل دیتابیس
اولین کار برای داشتن یک سایت چند زبانه، این است که یک مدل صحیح و مناسب را برای دیتابیس خود انتخاب کنید. یکی از اولین روشهایی که به ذهن هر فردی میرسد این است که برای هر ستون متنی که قرار است چند زبانه باشد، به تعداد زبانها برایش یک ستون در نظر بگیریم. یعنی برای جدول مقالات که قرار است در سه زبان فارسی و انگلیسی و عربی باشد، سه ستون برای عنوان مقاله و سه ستون نیز برای متن آن داشته باشیم. تصویر زیر نمونهای از این مدل را نشان میدهد.
مزایا:
- پیاده سازی آسان
معایب:
- در این روش با زیاد شدن هر زبان، تعداد ستونها افزایش مییابد که باعث میشود طراحی مناسبی نداشته باشد.
- در ضمن این مورد باید توسط برنامه نویس مرتبا اضافه گردد یا اینکه برنامه نویس این امکان را در سیستم قرار دهد که مدیر سایت بتواند در پشت صحنه کوئری افزودن ستون را ایجاد کند که باید جدول مرتبا مورد alter گرفتن قرار بگیرد.
- ممکن است همیشه برای هر زبانی مطلبی قرار نگیرد و این مورد باعث میشود بی جهت فضایی برای آن در نظر گرفته شود.
پی نوشت: با اینکه امروزه بحث فیلدهای sparse Column وجود دارد ولی این فیلدها در هر شرایطی مورد استفاده قرار نمیگیرند وبیشتر متعلق به زمانی است که میدانیم آن فیلد به شدت کم مورد استفاده قرار میگیرد.
پی نوشت دوم : در صورتی که فیلد شما مانند متن مقاله که عموما از نوع داده (varchar(max است استفاده میکنید و در صورتی که زبان مورد استفاده قرار نگیرد در خیلی از اوقات بی جهت فیلدهای Blob ساخته اید که بهینه سازی آن را نیز باید در نظر بگیرید.
ID | کد |
Language | زبان |
ISO | کد دو رقمی آن زبان |
Flag | پرچم آن کشور |
مزایا:
- پیاده سازی آسان
معایب:
- ایجاد رکوردهای تکراری، هر مقاله برای بعضی از اطلاعاتش که چند زبانه نیستند دادههای تکراری خواهد داشت.
- هر مقاله یک مقالهی جدا شناخته میشود و ارتباطی میان آنان نخواهد بود. بدین ترتیب توانایی ایجاد گزارشهایی چون هر گروه از مقاله و دسته بندی آنها از بین خواهد رفت. در ضمن مدیر عموما در یک سیستم مدیریتی میخواهد تنها یک لینک را به یک مقاله بدهد و سایت بنا به تشخیص در زبان مزبور، یکی از این مقالات را به کاربر نمایش دهد؛ نه اینکه مرتبا مدیر برای هر زبان، لینکی را مهیا کند و در این حالت چنین چیزی ممکن نخواهد بود.
- در یک سیستم فروشگاهی همانند تصویر بالا کار هم سختتر میشود و هر رکورد، یک محصول جدا شناخته میشود و ویرایشها هم برای هر کدام باید جداگانه صورت بگیرد که در عمل این طرح را رد میکند.
سومین راه حل این است که سه جدول ایجاد کنیم:
یک. جدول زبانها (که بالاتر ایجاد شده بود)
دو . جدول نام مقاله به همراه اطلاعات پایه و فیلدها بی نیاز به چند زبانه بودن
سه : یک جدول که هر دو ستون آن کدهای کلید دو جدول بالا را دارند و فیلدهای چند زبانه در آن وجود دارند.
جدول پایه
ID | کد |
Name | نام مقاله |
CreationDate | تاریخ ایجاد |
Writer | نویسنده |
Visibilty | وضعیت نمایش |
LanguageCode | کد زبان |
ArticleID | کد مقاله |
CreationDate | تاریخ ایجاد |
Visibility | وضعیت نمایش مقاله |
Title | عنوان مقاله |
ContentText | متن مقاله |
در جدول پایه یک مقاله ایجاد میشود که اطلاعات عمومی همه مقالات را دارد و حتی خصوصیت وضعیت نمایش آن، روی همهی مقالات با هر زبانی تاثیر میگذارد. در جدول دو، هر مقاله یک رکورد دارد که کد زبان و کد مقاله برای آن یک کلید ترکیبی به حساب میآیند. پس، از هر مقاله یک یا چند زبان خواهیم داشت. همچنین دارای فیلدهایی با وضعیت مخصوص به خود هم هستند؛ مثل فیلد وضعیت نمایش مقاله که فقط برای این مقاله با این زبان کاربرد دارد.
مزایا:
- گزارش گیری آسان برای هر دسته مقاله با زبانهای مختلف و ارتباط و یکپارچگی
- آسان در افزودن زبان.
معایب:
- ایجاد کوئریهای پیچیدهتر و جوین دار که به نسبت روشهای قبلی کوئریها پیچیدهتر شده اند.
- کدنویسی زیادتر.
استفاده از ساختارهای XML یا JSON برای ذخیره سازی اطلاعات چند زبانه مانند ساختارهای زیر:
XML<Articles> <Article> this is english text </Article> <Article> این یک متن فارسی است </Article> </Articles> یا <Articles> <en-us> this is english text </en-us> <fa-ir> این یک متن فارسی است </fa-ir> </Articles>
"Articles":["en-us':{"title":"this is english text","content":" english content"},"fa-ir":{"title":"متن فارسی","content":"محتوای فارسی"}]
از مزایای این روش ذخیرهی همه دادهها در یک ستون و یک جدول است و نیازی به ستونهای اضافه یا جداول اضافه نیست ولی معایب این روش استفاده از کوئریهای پیچیدهتر جهت ارتباط و خواندن است.
استفاده از بانکهای اطلاعاتی NO SQL
در این بانکها دیگر درگیر تعداد ستونها و جنس آنها نیستیم و میتوانیم برای هر مقاله یا محصول، هر تعداد زبان و یا فیلد را که میخواهیم، در نظر بگیریم و اضافه کنیم. برای آشنایی بیشتر با این نوع بانکها و انواع آن، مقالات مربوط به nosql را در سایت دنبال کنید.
نکاتی که در یک سایت چند زبانه باید به آنها توجه کرد.
یک . زبان آن صفحه را معرفی کنید: این کار هم به موتورهای جست و جو برای ثبت سایت شما کمک میکند و هم برای معلولین که از ابزارهای صفحه خوان استفاده میکنند، کمک بزرگی است. در این روش، صفحه خوانها و دستگاههای خط بریل که زبان صفحه را تشخیص نمیدهند با خواندن کد زبان میتوانند زبان صفحه را تشخیص دهند. با استفاده از خط زیر میتوانید زبان اصلی صفحهی خود را تنظیم نمایید:
<html lang="en">
اگر از XHTML استفاده میکنید خاصیت زیر را فراموش نکنید. دریافت W3C Validation بدون آن امکان پذیر نخواهد بود.
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<blockquote lang=”fr”> <p>Le plus grand faible des hommes, c'est l'amour qu'ils ont de la vie.</p> </blockquote>
سه. لینک ها : اگر دارید در صفحهای لینک به جایی میدهید که متفاوت از زبان شماست، حتما باید زبان صفحه یا سایت مقصد را مشخص کنید. مثلا لینک زیر برای صفحهای است که از یک زبان غیر فرانسوی به یک صفحهی با زبان فرانسوی هدایت میشود:
<a href="" hreflang="fr">French</a>
همچنین اگر متن لینک شما هم به زبان فرانسوی باشد خیلی خوب میشود که آن را هم بیان کنید و از خاصیت lang و هم hreflang همزمان استفاده کنید:
<a href="" hreflang="fr">Francais</a>
پنج. انکودینگ صفحه را مشخص کنید: برای اینکه نحوهی رمزگذاری و رمزگشایی حروف و نمادها مشخص گردد، باید انکودینگ تنظیم شود و حتی برای بعضی از موتورهای جست و جو که ممکن است با وب سایت شما به مشکل بر بخورند. امروزه بیشتر از صفحات یونیکد استفاده میشود که سطح وسیعی از کاراکترها را پشتیبانی میکند.
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
HTML5
<meta charset="UTF-8">
شش. اندازهی فونت: موقعی که یک سایت چند زبانه را طراحی میکنید این نکته خیلی مهم هست که بدانید اندازه فونتهای زبان پیش فرض، برای باقی زبانها مناسب نیستند. به عنوان مثال ممکن است اندازه فونتی برای زبانهای انگلیسی، فرانسوی و آلمانی مناسب باشد ولی برای زبانهای فارسی و عربی و چینی و ... مناسب نباشد و خواندن آن سخت شود. به همین جهت یکی از راههای حل این مشکل استفاده از قالب css است که وابسته به خصوصیت lang ای است که شما برای صفحه و هر المان یا تگی که از این خصوصیت استفاده میکند، تعیین کردهاید.
:lang(en) { font-size: 85%; font-family: arial, verdana, sans-serif; } :lang(zh) { font-size: 125%; font-family: helvetica, verdana, sans-serif; }
خط زیر تعیین میکند که از استایل اول استفاده شود:
<html lang="en">
<html lang="zh">
<body class="english"> or <body class="chinese">
و استایل:
.english { font-size: 85%; font-family: arial, verdana, sans-serif; } .chinese { font-size: 125%; font-family: helvetica, verdana, sans-serif; }
هشت : زمان را نیز تغییر دهید: یکی از مواردی که در کمتر سایت چند زبانهای به چشم میخورد و به نظر بنده میتواند بسیار مهم باشد این است که time zone منطقهی هر زبان را بدانید. به عنوان مثال برای مقالهی خود، تاریخ ایجاد را به صورت UTC ذخیره کنید و سپس نمایش را بر اساس زبان یا حتی بهتر و دقیقتر از طریق IP کشور مربوطه به دست آورید. برای کاربران ثبت نام شده این تاریخ میتواند دقیقتر باشد همانند انجمنهای وی بولتین.
شیوههای تشخیص زبان سایت
یکی از راههای تشخیص زبان این است که موقعی که برای اولین بار کاربری به سایت مراجعه میکند، زبان مورد نظرش را سوال کنید و این اطلاعات را در یک کوکی بدون تاریخ انقضاء ذخیره کنید تا در دفعات بعدی آن را بررسی نمایید.
دومین راه، استفاده از IP کاربر مراجعه کننده است تا بر اساس آن زبان مورد نظر را انتخاب کنید.
در سومین شیوه که اغلب استفاده میشود، زبان سایت به طور پیش فرض بر روی یک زبان خاص که بهتر است انگلیسی باشد تنظیم شده است و سپس کاربر از طریق یک منو یا ابزارهای موجود در سایت، زبان سایت را تغییر دهد.
پی نوشت: فراموش نگردد که امکان تغییر زبان همیشه برای کاربر مهیا باشد و طوری نباشد که کاربر در آینده نتواند زبان سایت را تغییر دهد؛ حتی اگر تشخیص خودکار سایت برای زبان فعال باشد.
پلاگینها و ابزارهای مدیریت زبانپی نوشت: در روشهای بالا بهتر است همان مرتبهی اول اطلاعات را در یک کوکی ذخیره کنید تا مراحل پیگیری راحتتر و آسانتر شود.
دومین ابزار که بیشتر برای انتخاب کشور میباشد و من خودم در بخش مدیریتی سیستمها از آن استفاده میکنم، ابزار CountrySelector است. این پلاگین قابلیت جست و جو زبان را همزمان با تایپ کاربر نیر داراست. اسامی کشورها به صورت انگلیسی شروع شده و به زبان آن کشور در داخل پرانتز خاتمه مییابند و پرچم هر کشور نیز در کنار آن قرار دارد. کار کردن با آن بسیار راحت بوده و مستنداتش به طور کامل کار با آن را توضیح میدهد.
پلاگین بعدی International Telephone Input است که پیاده سازی پلاگین بالا میباشد. برای مواردی مفید است که شما نیاز دارید کد تلفنی کشوری را انتخاب کنید.
در مقالههای زیر که در سایت جاری است در مورد Globalization و به خصوص استفاده از ریسورسها مطالب خوبی بیان شده است:
قسمت بیست و دوم آموزش MVC که مبحث Globalization را دنبال میکند.
قسمت اول از شش قسمت مباحث Globalization که دنبالهی آن را میتوانید در مقالهی خودش دنبال کنید.